2012-06-05 8 views
8

lo tanto, utilizar la siguiente utilidad para obtener el nombre de un campo/propiedad de una instancia de una clase ...Obtener el nombre de un campo de una clase sin una instancia

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

Esto me permite hacer lo siguiente:

public class CoolCat 
{ 
    public string KaratePower; 
} 

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

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

Esto es muy bueno para la serialización y otras veces cuando necesito una representación de cadena del nombre del campo.

Pero ahora, quiero poder obtener el nombre del campo SIN tener una instancia de la clase; por ejemplo, si estoy configurando una tabla y quiero vincular dinámicamente los FieldNames de las columnas con los campos reales en una clase (por lo que las refactorizaciones, etc. no lo romperán).

Básicamente, me siento como si simplemente no lo entiendo muy bien la sintaxis de cómo lograr esto, pero me imagino que va a ser algo como esto:

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

espero que tenga sentido - I' No soy muy bueno con el vocabulario sobre este tema, así que sé que la pregunta es un poco vaga.

Respuesta

3

Tengo dos métodos que utilizo para hacer esto.

El primero es un método de extensión que se puede usar en cualquier objeto.

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

cual se utiliza como

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

El segundo uso cuando no tengo un objeto.

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

Esto puede ser usado como tal

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

Me gusta mucho esta solución. ¿Podría explicar la sección que agregó al manejar las propiedades de Nullable ? ¿Cuándo se usaría esta sección de código? – William

+0

Si KaratePower es un 'Nullable ' o 'T?' Como 'int?' O 'DateTime?', Entonces el cuerpo no será un MemberExpression, será un UnaryExpression. A partir de ahí, debe tomar el Operando de UnaryExpression para obtener la MemberExpression correcta. – cadrell0

4

Lo que estamos tratando de hacer es una de las razones Microsoft creó System.Reflection Prueba 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

Tenga en cuenta que esto devolverá todas las propiedades estáticas públicas. En el ejemplo, se usa un campo no estático. –

+0

No estoy seguro de que esto me ayude. Quiero tener un método al que pueda llamar que devuelva el nombre de la cadena del campo de una clase determinada. ¿Cómo puedo convertir lo anterior en algo así? – William

+0

@William He actualizado mi ejemplo con su solicitud, puede llamarlo usando: GetClassPropertyNames (typeof (CoolCat)); –

2

Creo usando reflexión será útil en este caso. No tengo VS en este momento, pero estoy seguro de que puedes hacer algo como typeof (clase) .GetMembers(). Mi reflejo es un poco oxidado.

Cuestiones relacionadas