2010-01-12 13 views
115

गुणों के साथ कक्षा में किसी संपत्ति को देखते हुए - यह निर्धारित करने का सबसे तेज़ तरीका क्या है कि इसमें कोई विशेषता है या नहीं? उदाहरण के लिए:जांच करें कि संपत्ति का गुण

[IsNotNullable] 
    [IsPK] 
    [IsIdentity] 
    [SequenceNameAttribute("Id")] 
    public Int32 Id 
    { 
     get 
     { 
      return _Id; 
     } 
     set 
     { 
      _Id = value; 
     } 
    } 

यह निर्धारित करने का सबसे तेज़ तरीका क्या है कि उदाहरण के लिए इसमें "IsIdentity" विशेषता है?

उत्तर

209

विशेषताएँ पुनर्प्राप्त करने का कोई तेज़ तरीका नहीं है। लेकिन कोड (Aaronaught को ऋण) इस तरह दिखना चाहिए:

var t = typeof(YourClass); 
var pi = t.GetProperty("Id"); 
var hasIsIdentity = Attribute.IsDefined(pi, typeof(IsIdentity)); 

आप विशेषता गुण तो

var t = typeof(YourClass); 
var pi = t.GetProperty("Id"); 
var attr = (IsIdentity[])pi.GetCustomAttributes(typeof(IsIdentity), false); 
if (attr.Length > 0) { 
    // Use attr[0], you'll need foreach on attr if MultiUse is true 
} 
+52

यदि आपको केवल विशेषता के अस्तित्व की जांच करने की आवश्यकता है, और 'विशेषता' के माध्यम से, किसी भी जानकारी को पुनर्प्राप्त करने की आवश्यकता नहीं है, तो कोड की एक पंक्ति और बदसूरत सरणी/कास्टिंग समाप्त हो जाएगी। – Aaronaught

38

आप .NET 3.5 का उपयोग कर रहे हैं, तो आप अभिव्यक्ति के पेड़ के साथ की कोशिश कर सकते पुनः प्राप्त करने की जरूरत है।

class CustomAttribute : Attribute { } 

class Program 
{ 
    [Custom] 
    public int Id { get; set; } 

    static void Main() 
    { 
     Expression<Func<Program, int>> expression = p => p.Id; 
     var memberExpression = (MemberExpression)expression.Body; 
     bool hasCustomAttribute = memberExpression 
      .Member 
      .GetCustomAttributes(typeof(CustomAttribute), false).Length > 0; 
    } 
} 
+6

FYI आपके उत्तर के बारे में एक प्रश्न पूछा गया है। http://stackoverflow.com/questions/4158996/why-are-expression-trees-safer-than-reflection – Greg

11

आप एक आम (सामान्य) पद्धति का उपयोग कर सकते हैं एक दिया MemberInfo

public static bool TryGetAttribute<T>(MemberInfo memberInfo, out T customAttribute) where T: Attribute { 
       var attributes = memberInfo.GetCustomAttributes(typeof(T), false).FirstOrDefault(); 
       if (attributes == null) { 
        customAttribute = null; 
        return false; 
       } 
       customAttribute = (T)attributes; 
       return true; 
      } 
5

से अधिक विशेषता को पढ़ने के लिए अद्यतन करने के लिए और/या @Hans Passant मैं करूंगा द्वारा जवाब में वृद्धि: यह प्रतिबिंब अधिक सुरक्षित है संपत्ति के पुनर्प्राप्ति को एक विस्तार विधि में अलग करें। इस विधि getProperty()

public static class PropertyHelper<T> 
{ 
    public static PropertyInfo GetProperty<TValue>(
     Expression<Func<T, TValue>> selector) 
    { 
     Expression body = selector; 
     if (body is LambdaExpression) 
     { 
      body = ((LambdaExpression)body).Body; 
     } 
     switch (body.NodeType) 
     { 
      case ExpressionType.MemberAccess: 
       return (PropertyInfo)((MemberExpression)body).Member; 
      default: 
       throw new InvalidOperationException(); 
     } 
    } 
} 

आपका परीक्षण तो दो पंक्तियों

var property = PropertyHelper<MyClass>.GetProperty(x => x.MyProperty); 
Attribute.IsDefined(property, typeof(MyPropertyAttribute)); 
5

लिए कम हो जाता है तुम क्या करने की कोशिश कर रहे हैं, तो में बुरा जादू स्ट्रिंग को दूर करने के अतिरिक्त लाभ है कि एक पोर्टेबल कक्षा में लाइब्रेरी पीसीएल (मेरे जैसे), तो आप निम्न तरीके से यह कर सकते हैं :) है

public class Foo 
{ 
    public string A {get;set;} 

    [Special] 
    public string B {get;set;} 
} 

var type = typeof(Foo); 

var specialProperties = type.GetRuntimeProperties() 
    .Where(pi => pi.PropertyType == typeof (string) 
     && pi.GetCustomAttributes<Special>(true).Any()); 

तुम तो गुण इस विशेष संपत्ति है कि अगर आप की जरूरत की संख्या पर देख सकते हैं।

1

यह एक बहुत पुराना सवाल है, लेकिन मैं प्रयोग किया जाता

मेरे विधि इस पैरामीटर है, लेकिन यह बनाया जा सकता है:

Expression<Func<TModel, TValue>> expression 
विधि इस में

तब:

System.Linq.Expressions.MemberExpression memberExpression 
     = expression.Body as System.Linq.Expressions.MemberExpression; 
Boolean hasIdentityAttr = System.Attribute 
     .IsDefined(memberExpression.Member, typeof(IsIdentity)); 
1

यह कर सकते हैं अब नई सी # फीचर nameof() के साथ एक प्रकार सुरक्षित तरीके से अभिव्यक्ति पेड़ और विस्तार विधियों के बिना किया जाना चाहिए:

Attribute.IsDefined(typeof(YourClass).GetProperty(nameof(YourClass.Id)), typeof(IsIdentity)); 
संबंधित मुद्दे