किसी विशिष्ट संपत्ति का प्रॉपर्टीइन्फो कैसे प्राप्त करें?


82

मैं एक विशिष्ट संपत्ति के लिए PropertyInfo प्राप्त करना चाहता हूं। मैं प्रयोग कर सकता हूँ:

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

लेकिन ऐसा ही कुछ करने का एक तरीका होना चाहिए

typeof(MyProperty) as PropertyInfo

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

चीयर्स।

जवाबों:


61

आप नए nameof()ऑपरेटर का उपयोग कर सकते हैं जो C # 6 का हिस्सा है और Visual Studio 2015 में उपलब्ध है। अधिक जानकारी यहाँ

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

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

कंपाइलर nameof(MyObject.MyProperty)स्ट्रिंग को "MyProperty" में बदल देगा, लेकिन आप स्ट्रिंग को बदलने के लिए याद रखने के बिना संपत्ति के नाम को फिर से प्राप्त करने में सक्षम होने का लाभ प्राप्त करते हैं क्योंकि विज़ुअल स्टूडियो, रेस्परर, और जैसे कि पता है कि रिफ्लेक्टर को कैसे पहचाना जाता nameof()है।


1
यदि आपके उदाहरण के PropertyInfo result =बजाय इसके साथ शुरू हुआ तो यकीनन थोड़ा स्पष्ट हो जाएगा var result =
डेविड आरआर

134

वहाँ एक है। Lambdas के साथ 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();
        }
    }
}

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

1
2.0 में, वोजिस्लाव स्टोजकोविक का जवाब निकटतम है जो आप प्राप्त कर सकते हैं।
मार्क Gravell

4
एक सवाल: अर्क होने से पहले "शरीर पर लम्बोदर एक्सप्रेशन" क्यों होता है? चयनकर्ता हमेशा एक लैम्ब्डाएक्सप्रेशन नहीं होता है?
बाघिन

@tigrou बहुत संभव है सिर्फ एक निरीक्षण, और शायद मुझे मौजूदा कोड है कि बस के खिलाफ काम किया उधारExpression
मार्क Gravell

@MarcGravell यह कार्यान्वयन बहुत ध्वनि नहीं है। के मामले में आपको सही संपत्ति की जानकारी नहीं मिलती है PropertyHelper<Derived>.GetProperty(x => x.BaseProperty);। देखें stackoverflow.com/questions/6658669/...
nawfal

13

तुम यह केर सकते हो:

typeof(MyObject).GetProperty("MyProperty")

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


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

1

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


5
यही ओपी बचने की कोशिश कर रहा है। यकीन नहीं होता अगर यह सवाल का जवाब देता है।
नवफाल

संकलित समय बनाम रन समय और ओपी के मूल इरादे के बारे में अच्छी बात हालांकि हार्डकॉक्ड स्ट्रिंग्स से बचना अभी भी सबसे साफ समाधान लगता है - टाइपोस की संभावना से बचा जाता है, आसान रीफैक्टरिंग के लिए अनुमति देता है और क्लीनर कोड शैली के लिए बनाता है।
ब्रायन स्वीनी
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.