2008-11-07 11 views
34

Estoy tratando de escribir una función que se tire el nombre de una propiedad y el tipo de uso de la sintaxis, como a continuación:Obtener nombre de propiedad y escribir con expresión lambda

private class SomeClass 
{ 
    Public string Col1; 
} 

PropertyMapper<Somewhere> propertyMapper = new PropertyMapper<Somewhere>(); 
propertyMapper.MapProperty(x => x.Col1) 

¿Hay alguna manera de pasar la propiedad a través a la función sin ningún cambio importante a esta sintaxis?

Me gustaría obtener el nombre de la propiedad y el tipo de propiedad.

Así en el ejemplo siguiente que me gustaría recuperar

Name = "Col1" y Type = "System.String"

¿Alguien puede ayudar?

+0

¿Cuál es la imagen más grande? ¿Por qué no simplemente pasar "Col1" como un nombre de cadena y usar la reflexión para encontrar ese miembro? ¿Qué motiva a la lambda? – Brian

+12

Estoy trabajando en un ORM interno para mi trabajo. Quiero apoyar fácilmente el cambio de nombres de propiedad sin tener que buscar cadenas por todos lados, además de dar (en mi opinión) una sintaxis limpia – pythonandchips

Respuesta

59

Aquí basta de un ejemplo del uso Expressions para obtener el nombre de una propiedad o campo para empezar:

public static MemberInfo GetMemberInfo<T, U>(Expression<Func<T, U>> expression) 
{ 
    var member = expression.Body as MemberExpression; 
    if (member != null) 
     return member.Member; 

    throw new ArgumentException("Expression is not a member access", "expression"); 
} 

se vería así Prefijo telefónico:

public class Program 
{ 
    public string Name 
    { 
     get { return "My Program"; } 
    } 

    static void Main() 
    { 
     MemberInfo member = ReflectionUtility.GetMemberInfo((Program p) => p.Name); 
     Console.WriteLine(member.Name); 
    } 
} 

Una palabra de pero cuidado: la simple declaración de (Program p) => p.Name en realidad implica bastante trabajo (y puede tomar cantidades mensurables de tiempo). Considere almacenar en caché el resultado en lugar de llamar al método con frecuencia.

+6

Recuerde siempre que una expresión lambda se puede convertir en un delegado o un árbol de expresiones. –

+1

Advertencia: la implementación GetMemberInfo no es muy segura - http://stackoverflow.com/questions/6658669/lambda-expression-not-returning-expected-memberinfo.Dicho esto, puedes usarlo solo para leer el nombre. Pero la información del miembro devuelto en sí misma no será precisa. – nawfal

3

Me pareció muy útil.

public class PropertyMapper<T> 
{ 
    public virtual PropertyInfo PropertyInfo<U>(Expression<Func<T, U>> expression) 
    { 
     var member = expression.Body as MemberExpression; 
     if (member != null && member.Member is PropertyInfo) 
      return member.Member as PropertyInfo; 

     throw new ArgumentException("Expression is not a Property", "expression"); 
    } 

    public virtual string PropertyName<U>(Expression<Func<T, U>> expression) 
    { 
     return PropertyInfo<U>(expression).Name; 
    } 

    public virtual Type PropertyType<U>(Expression<Func<T, U>> expression) 
    { 
     return PropertyInfo<U>(expression).PropertyType; 
    } 
} 

Hice esta pequeña clase para seguir la solicitud original. Si necesita el nombre de la propiedad se puede utilizar de esta manera:

PropertyMapper<SomeClass> propertyMapper = new PropertyMapper<SomeClass>(); 
string name = propertyMapper.PropertyName(x => x.Col1); 
2

Sólo pensé que volvería a poner esto aquí para construir en el enfoque anterior.

public static class Helpers 
{ 
    public static string PropertyName<T>(Expression<Func<T>> expression) 
    { 
     var member = expression.Body as MemberExpression; 
     if (member != null && member.Member is PropertyInfo) 
      return member.Member.Name; 

     throw new ArgumentException("Expression is not a Property", "expression"); 
    } 
} 

entonces le puede llamar de la siguiente manera:

Helpers.PropertyName(() => TestModel.TestProperty); 

También debo señalar que, con el VS 2015 y C# 6.0 puede simplemente usar nombredel.

https://msdn.microsoft.com/en-us/library/dn986596.aspx

3

Esto se puede hacer fácilmente en C# 6. Para obtener el nombre del operador de uso de la propiedad nombredel.

nameof(User.UserId) 

y obtener el tipo de propiedad typeof operador.

typeof(User.UserId) 
Cuestiones relacionadas