2012-06-05 13 views
8

तो मैं निम्नलिखित उपयोगिता का उपयोग एक वर्ग का एक उदाहरण से कोई फ़ील्ड/गुण का नाम प्राप्त करने के लिए बिना एक वर्ग से एक क्षेत्र के प्राप्त करें ...एक उदाहरण

public static string FieldName<T>(Expression<Func<T>> Source) 
{ 
    return ((MemberExpression)Source.Body).Member.Name; 
} 

यह मैं के लिए अनुमति देता

public class CoolCat 
{ 
    public string KaratePower; 
} 

public class Program 
{ 
    public static Main() 
    { 
     public CoolCat Jimmy = new CoolCat(); 

     string JimmysKaratePowerField = FieldName(() => Jimmy.KaratePower); 
    } 
} 

यह क्रमबद्धता और अन्य समय के लिए महान जब मैं फ़ील्ड नाम के एक स्ट्रिंग प्रतिनिधित्व की आवश्यकता है: निम्न कार्य करें।

लेकिन अब, मैं कक्षा का उदाहरण होने के बिना फ़ील्ड नाम प्राप्त करने में सक्षम होना चाहता हूं - उदाहरण के लिए, यदि मैं एक टेबल स्थापित कर रहा हूं और कॉलम के फ़ील्ड नामों को गतिशील रूप से लिंक करना चाहता हूं कक्षा (इसलिए refactorings, आदि इसे तोड़ नहीं होगा)।

मूल रूप से, मुझे लगता है कि मैं सिर्फ काफी यह कैसे पूरा करने के लिए की वाक्य रचना नहीं मिलता है, लेकिन मुझे लगता है कि यह कुछ इस तरह दिखेगा:

public static string ClassFieldName<T>(Func<T> PropertyFunction) 
{ 
    // Do something to get the field name? I'm not sure whether 'Func' is the right thing here - but I would imagine that it is something where I could pass in a lambda type expression or something of the sort? 
} 

public class Program 
{ 
    public static Main() 
    { 
     string CatsPowerFieldName = ClassFieldName<CoolCat>((x) => x.KaratePower); 

     // This 'CatsPowerFieldName' would be set to "KaratePower". 
    } 
} 

मुझे आशा है कि समझ में आता है - मैं मैं इस विषय के आसपास vocab के साथ बहुत अच्छा नहीं है तो मुझे पता है कि सवाल थोड़ा अस्पष्ट है।

using System.Reflection; // reflection namespace 

public static List<Type> GetClassPropertyNames(Type myClass) 
     { 
      PropertyInfo[] propertyInfos; 
      propertyInfos = myClass.GetProperties(BindingFlags.Public); 

      List<Type> propertyTypeNames = new List<Type>(); 

      // write property names 
      foreach (PropertyInfo propertyInfo in propertyInfos) 
      { 
       propertyTypeNames .Add(propertyInfo.PropertyType); 
      } 

      return propertyNames; 

     } 

उत्तर

3

मेरे पास ऐसा करने के लिए दो विधियां हैं जिनका उपयोग मैं करता हूं।

पहला एक विस्तार विधि है जिसका उपयोग किसी ऑब्जेक्ट पर किया जा सकता है।

public static string GetPropertyName<TEntity, TProperty>(this TEntity entity, Expression<Func<TEntity, TProperty>> propertyExpression) 
{ 
    return propertyExpression.PropertyName(); 
} 

जब मैं एक वस्तु की जरूरत नहीं है कौन सा तरह

public CoolCat Jimmy = new CoolCat(); 
string JimmysKaratePowerField = Jimmy.GetPropertyName(j => j.KaratePower); 

दूसरा मैं का उपयोग किया जाता है।

public static string PropertyName<T>(this Expression<Func<T, object>> propertyExpression) 
{ 
     MemberExpression mbody = propertyExpression.Body as MemberExpression; 

     if (mbody == null) 
     { 
      //This will handle Nullable<T> properties. 
      UnaryExpression ubody = propertyExpression.Body as UnaryExpression; 

      if (ubody != null) 
      { 
       mbody = ubody.Operand as MemberExpression; 
      } 

      if (mbody == null) 
      { 
       throw new ArgumentException("Expression is not a MemberExpression", "propertyExpression"); 
      } 
     } 

     return mbody.Member.Name; 
} 

इस तरह तो

string KaratePowerField = Extensions.PropertyName<CoolCat>(j => j.KaratePower); 
+0

मुझे वास्तव में यह समाधान पसंद है - क्या आप शायद उस अनुभाग के बारे में विस्तार से बता सकते हैं जिसे आपने Nullable गुणों को संभालने में जोड़ा है? कोड के इस खंड का उपयोग कब किया जाएगा? – William

+0

यदि कराटेपावर 'Nullable ' या 'टी? 'जैसे' int? 'या' डेटटाइम 'है, तो शरीर सदस्य एक्सप्लशन नहीं होगा, यह एक यूनरीएक्सप्रेस होगा। वहां से, आपको सही सदस्य एक्स्प्रेशन प्राप्त करने के लिए UnaryExpression's Operand लेने की आवश्यकता है। – cadrell0

4

तुम क्या करने की कोशिश कर रहे किन वजहों से माइक्रोसॉफ्ट System.Reflection बनाया this प्रयास करें से एक है। मेरे पास अभी मेरे साथ वीएस नहीं है, लेकिन मुझे यकीन है कि आप टाइपऑफ (क्लास) जैसे कुछ कर सकते हैं .GetMembers()। मेरा प्रतिबिंब थोड़ा जंगली है।

+0

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

+0

मुझे यकीन नहीं है कि यह मेरी मदद करता है - मैं एक तरीका चाहता हूं जिसे मैं कॉल कर सकता हूं जो किसी दिए गए वर्ग के क्षेत्र का स्ट्रिंग नाम देता है - मैं उपरोक्त को इस तरह से कैसे बदल सकता हूं? – William

+0

@ विलियम मैंने आपके अनुरोध के साथ अपना उदाहरण अपडेट कर लिया है, आप इसका उपयोग कर कॉल कर सकते हैं: GetClassPropertyNames (टाइपऑफ (कूलकैट)); –

2

मैं प्रतिबिंब का उपयोग कर यहाँ उपयोगी होगा विश्वास करते हैं:

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