2009-01-29 21 views
66

मैं एक विशिष्ट संपत्ति के लिए PropertyInfo प्राप्त करना चाहता हूं। मैं इस्तेमाल कर सकते हैं:किसी विशिष्ट संपत्ति का PropertyInfo कैसे प्राप्त करें?

foreach(PropertyInfo p in typeof(MyObject).GetProperties()) 
{ 
    if (p.Name == "MyProperty") { return p } 
} 

लेकिन

typeof(MyProperty) as PropertyInfo 

के लिए इसी तरह कुछ करने के लिए एक तरीका होता है वहाँ होना चाहिए? या मैं एक प्रकार की असुरक्षित स्ट्रिंग तुलना कर रहा हूँ?

चीयर्स।

उत्तर

33

आप नए nameof() ऑपरेटर कि विजुअल स्टूडियो 2015 में सी # 6 का हिस्सा है और उपलब्ध है उपयोग कर सकते हैं अधिक जानकारी here

अपने उदाहरण के लिए आप का प्रयोग करेंगे:

PropertyInfo result = typeof(MyObject).GetProperty(nameof(MyObject.MyProperty)); 

संकलक स्ट्रिंग "MyProperty" करने के लिए nameof(MyObject.MyProperty) में परिवर्तित कर देंगे, लेकिन आप उस प्रॉपर्टी नाम refactor करने में सक्षम होने का लाभ प्राप्त करता बिना स्ट्रिंग को बदलने के लिए याद करने के लिए क्योंकि विजुअल स्टूडियो, रीशेपर, और जैसे nameof() मानों को पुन: सक्रिय करने के बारे में जानते हैं।

+1

देखें यदि आपका उदाहरण 'varIn =' के बजाय 'PropertyInfo result =' के साथ शुरू हुआ है तो यह थोड़ा सा स्पष्ट होगा। । – DavidRR

10

आप ऐसा कर सकते हैं:

typeof(MyObject).GetProperty("MyProperty") 

हालांकि, बाद से सी # एक "प्रतीक" प्रकार नहीं है, वहाँ कुछ भी नहीं आप स्ट्रिंग का उपयोग करने से बचने में मदद मिलेगी है। आप इस प्रकार से असुरक्षित क्यों कहते हैं?

+32

क्योंकि संकलन समय पर इसका मूल्यांकन नहीं किया जाता है? अगर मैंने अपना प्रॉपर्टी नाम बदल दिया है या स्ट्रिंग टाइप किया है तो कोड नहीं चलने तक मुझे पता नहीं चलेगा। – tenpn

0

प्रतिबिंब का उपयोग रनटाइम प्रकार मूल्यांकन के लिए किया जाता है। इसलिए संकलन समय पर आपके स्ट्रिंग स्थिरांक को सत्यापित नहीं किया जा सकता है।

+5

यही वह है जो ओपी से बचने की कोशिश कर रहा है। निश्चित नहीं है कि यह सवाल का जवाब देता है। – nawfal

+0

संकलन समय बनाम रन टाइम और ओपी के मूल उद्देश्य के बारे में अच्छा बिंदु हालांकि हार्डकोडेड तारों से परहेज करना अभी भी सबसे साफ समाधान प्रतीत होता है - टाइपो की संभावना से बचाता है, आसान रिफैक्टरिंग की अनुमति देता है और क्लीनर कोड शैली बनाता है। –

120

lambdas के साथ एक .NET 3.5 रास्ता/Expression कि तार का उपयोग नहीं करता है ...

using System; 
using System.Linq.Expressions; 
using System.Reflection; 

class Foo 
{ 
    public string Bar { get; set; } 
} 
static class Program 
{ 
    static void Main() 
    { 
     PropertyInfo prop = PropertyHelper<Foo>.GetProperty(x => x.Bar); 
    } 
} 
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(); 
     } 
    } 
} 
+0

अच्छा समाधान लेकिन दुर्भाग्य से मैं .NET3.5 का उपयोग नहीं कर रहा हूं। फिर भी, टिक! – tenpn

+1

2.0 में, Vojislav Stojkovic का जवाब सबसे नज़दीकी है जो आप प्राप्त कर सकते हैं। –

+4

एक सवाल: निष्कर्ष निकालने से पहले "शरीर LambdaExpression" पर एक परीक्षण क्यों है। कोई संपत्ति? चयनकर्ता हमेशा एक LambdaExpression नहीं है? – tigrou

संबंधित मुद्दे