किसी विशेषता के साथ गुणों की सूची कैसे प्राप्त करें?


210

मेरे पास एक प्रकार है, tऔर मैं उन सार्वजनिक गुणों की एक सूची प्राप्त करना चाहूंगा जिनके पास विशेषता है MyAttribute। विशेषता को AllowMultiple = falseइस तरह से चिह्नित किया गया है :

[AttributeUsage(AttributeTargets.Property, AllowMultiple = false)]

वर्तमान में मेरे पास क्या है, लेकिन मैं सोच रहा हूं कि एक बेहतर तरीका है:

foreach (PropertyInfo prop in t.GetProperties())
{
    object[] attributes = prop.GetCustomAttributes(typeof(MyAttribute), true);
    if (attributes.Length == 1)
    {
         //Property with my custom attribute
    }
}

मैं इसे कैसे सुधार सकता हूं? मेरी क्षमा याचना अगर यह एक डुप्लिकेट है, तो वहां से एक टन प्रतिबिंब निकलता है ... ऐसा लगता है कि यह काफी गर्म विषय है।


नहीं। इससे पहले कि आप यह पता लगा सकें कि प्रॉपर्टी में कोई गुण है, आपको प्रॉपर्टीइन्फो की जरूरत है।
हंस पैसेंट

जवाबों:


391
var props = t.GetProperties().Where(
                prop => Attribute.IsDefined(prop, typeof(MyAttribute)));

यह किसी भी विशेषता उदाहरण (यानी यह से सस्ता है) को अमल में लाने से बचा जाता है GetCustomAttribute[s]()


1
अच्छा सुझाव। हालांकि मुझे विशेषता उदाहरण की आवश्यकता होगी, लेकिन मुझे यह पसंद है।
वन्सविले

1
मैं सिर्फ एक गुण के अस्तित्व की जांच करने के लिए एक रास्ता खोज रहा था, जो उस पक्ष-प्रभाव के बिना है जिसे संपत्ति कहा जाता है। धन्यवाद मार्क, यह काम!
atrrr Jämte

1
@ CalledrjanJämte का getउपयोग करते समय भी संपत्ति को नहीं बुलाया जाता है GetCustomAttributes; हालाँकि, विशेषता त्वरित है , जो मुफ़्त नहीं है। यदि आपको विशेषता के विशिष्ट मूल्यों की जांच करने की आवश्यकता नहीं है, IsDefinedतो सस्ता है। और 4.5 में, वहाँ इन्स्टेन्शियशन डेटा रोकने के तरीके हैं बिना वास्तव में किसी भी विशेषता उदाहरणों बनाने (हालांकि यह है इरादा बहुत विशिष्ट परिदृश्यों के लिए केवल)
मार्क Gravell


2
डॉटनेट कोर के लिए: var props = t.GetProperties ()। जहाँ (e => e.IsDefined (टाइपो (MyAttribute)));
Rtype

45

जो समाधान मैं सबसे अधिक उपयोग कर रहा हूं, वह टॉमस पेट्रिसक के उत्तर पर आधारित है। मैं आमतौर पर विशेषता और संपत्ति दोनों के साथ कुछ करना चाहता हूं ।

var props = from p in this.GetType().GetProperties()
            let attr = p.GetCustomAttributes(typeof(MyAttribute), true)
            where attr.Length == 1
            select new { Property = p, Attribute = attr.First() as MyAttribute};

+1 - "मैं आमतौर पर विशेषता और संपत्ति दोनों के साथ कुछ करना चाहता हूं" जो मैं देख रहा था - आपका उत्तर पोस्ट करने के लिए बहुत धन्यवाद!
यवर मुर्तजा

34

जहाँ तक मुझे पता है, एक बेहतर तरीके से रिफ्लेक्शन लाइब्रेरी के साथ काम करने के मामले में कोई बेहतर तरीका नहीं है। हालाँकि, आप कोड को थोड़ा अच्छा बनाने के लिए LINQ का उपयोग कर सकते हैं:

var props = from p in t.GetProperties()
            let attrs = p.GetCustomAttributes(typeof(MyAttribute), true)
            where attrs.Length != 0 select p;

// Do something with the properties in 'props'

मेरा मानना ​​है कि यह आपको अधिक पठनीय अंदाज में कोड संरचना करने में मदद करता है।



6

यदि आप परावर्तन में गुण के साथ नियमित रूप से व्यवहार करते हैं, तो कुछ विस्तार विधियों को परिभाषित करना बहुत ही व्यावहारिक है। आप देखेंगे कि कई परियोजनाओं में से एक है। यह एक है जो मैं अक्सर है:

public static bool HasAttribute<T>(this ICustomAttributeProvider provider) where T : Attribute
{
  var atts = provider.GetCustomAttributes(typeof(T), true);
  return atts.Length > 0;
}

जिसे आप पसंद कर सकते हैं typeof(Foo).HasAttribute<BarAttribute>();

अन्य प्रोजेक्ट्स (जैसे स्ट्रक्च्योरपार्ट) में फुलफिल्ड रिफ्लेक्शन हेल्पर क्लास हैं जो एक्सप्रेशन ट्री का इस्तेमाल करते हैं ताकि प्रॉपर्टीइन्फ़ॉस की पहचान के लिए एक बढ़िया सिंटैक्स हो। उपयोग तब ऐसा दिखता है:

ReflectionHelper.GetProperty<Foo>(x => x.MyProperty).HasAttribute<BarAttribute>()

2

पिछले उत्तरों के अलावा: Any()संग्रह की जाँच लंबाई के बजाय विधि का उपयोग करना बेहतर है :

propertiesWithMyAttribute = type.GetProperties()
  .Where(x => x.GetCustomAttributes(typeof(MyAttribute), true).Any());

Dotnetfiddle: https://dotnetfiddle.net/96mKep पर उदाहरण


@ cogumel0 सबसे पहले, यकीन .Any()है कि लंबाई की जाँच नहीं करता है। लेकिन मेरा जवाब बिल्कुल एक विशेषता के साथ पाया गुणों के बारे में नहीं था। दूसरा, मुझे यकीन नहीं है कि आप कोड को सही तरीके से पढ़ते हैं - .Anyविधि के परिणाम पर कहा जाता है GetCustomAttrubutes। तो propertiesWithMyAttributeवसीयत का प्रकार गुणों का संग्रह होगा। Dotnetfiddle पर उदाहरण देखें (मैं उत्तर के लिए लिंक जोड़ता हूं)।
10

1
आप प्रतिस्थापित कर सकते हैं। किसी के साथ, कहीं से भी। कोई भी लैम्ब्डा की अनुमति देता है।
PRMan
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.