2012-06-05 26 views
8

więc używam następujące narzędzia, aby uzyskać nazwę pola/nieruchomość z instancji klasy ...Uzyskaj nazwę pola z klasy bez instancji

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

To pozwala mi Wykonaj następujące czynności:

public class CoolCat 
{ 
    public string KaratePower; 
} 

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

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

Jest to idealne rozwiązanie do serializacji i innych sytuacji, gdy potrzebuję reprezentacji łańcuchowej nazwy pola.

Ale teraz chcę mieć możliwość otrzymania nazwy pola BEZ instancji klasy - na przykład, jeśli konfiguruję tabelę i chcę dynamicznie łączyć FieldNames kolumn z rzeczywistymi polami w klasa (więc refaktoryzacja itp. go nie przerwie).

Zasadniczo, czuję się po prostu nie dość dostać składnię, jak tego dokonać, ale wyobrażam sobie, że będzie to wyglądać mniej więcej tak:

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". 
    } 
} 

Mam nadzieję, że sens - I” Nie jestem zbyt dobry w odniesieniu do tego tematu, więc wiem, że pytanie jest trochę niejasne.

Odpowiedz

3

Mam dwie metody używam to zrobić.

Pierwsza to metoda rozszerzenia, którą można zastosować do dowolnego obiektu.

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

które służy jak

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

drugim używam, kiedy nie mam obiekt.

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; 
} 

ten może być używany jak tak

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

Naprawdę podoba mi się to rozwiązanie - czy mógłbyś omówić sekcję dodaną do właściwości Nullable ? Kiedy należy użyć tej części kodu? – William

+0

Jeśli KaratePower jest 'Nullable ' lub 'T?' Takie jak 'int?' Lub 'DateTime?', To ciało nie będzie MemberExpression, będzie to UnaryExpression. Stamtąd musisz wziąć operand UnaryExpression, aby uzyskać poprawną wartość MemberExpression. – cadrell0

4

Co starasz się zrobić, to jeden z powodów, Microsoft stworzył System.Reflection Zajrzyj this:

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; 

     } 
+0

Zauważ, że to zwróci wszystkie publiczne właściwości statycznych. W tym przykładzie użyto pola niestatycznego. –

+0

Nie jestem pewien, czy to mi pomoże - chcę mieć metodę, którą mogę nazwać, która zwraca nazwę ciągu pola danej klasy - jak mogę zmienić powyższe w coś takiego? – William

+0

@William Zaktualizowałem swój przykład o Twoją prośbę, możesz zadzwonić pod następujący adres: GetClassPropertyNames (typeof (CoolCat)); –

2

wierzę użyciu odbicia będą przydatne tutaj. Nie mam teraz VS ze mną, ale jestem pewien, że możesz zrobić coś takiego jak typeof (klasa) .GetMembers(). Moje odbicie jest trochę zardzewiałe.

Powiązane problemy