net - propertyinfo c#
Obteniendo el nombre de un campo en c# (6)
Dada esta clase:
public class MyClass
{
public int MyField {get; set;}
}
¿Cómo podré extraer el nombre de MyField
en código?
Por ejemplo, puedo obtener el nombre de la clase como este
typeof(MyClass).Name
¿Cómo puedo hacer algo similar para el campo?
El motivo de la pregunta es que quiero que este código en particular sea resistente a las refactorizaciones de los nombres.
EDITAR: Con resistente quiero decir que quiero que el código en el sitio de la llamada sea robusto ante los cambios del nombre de campo. Tengo algunas cosas que están usando una representación de cadena del nombre del campo. Perdón por las malas frases. No incluí el código del sitio de llamadas para mantener limpio el problema y no desviarme hacia otras discusiones sobre la naturaleza del código del sitio de llamadas.
Con C # 6.0, puede usar el nuevo nameof
operador.
nameof(MyClass.MyField) // returns "MyField"
nameof(MyClass) //returns "MyClass"
Ver nameof (C # y referencia de Visual Basic) para más ejemplos.
En C # 6 podemos hacerlo muy simple.
nameof(MyField);
puede obtener el método / type / propery / field / class / namespace names de la misma manera ex
nameof(MyClass);
nameof(namespacename1) // returns "namespacename1"
nameof(TestEnum.FirstValue) // returns enum''s first value
Lo haces así, usando árboles de expresión generados por compilador:
public static string GetMemberName<T, TValue>(Expression<Func<T, TValue>> memberAccess)
{
return ((MemberExpression)memberAccess.Body).Member.Name;
}
Ahora llama al método estático desde el código:
class MyClass
{
public int Field;
public string Property { get; set; }
}
var fieldName = GetMemberName((MyClass c) => c.Field);
var propertyName = GetMemberName((MyClass c) => c.Property);
// fieldName has string value of `Field`
// propertyName has string value of `Property`
Ahora también puede usar la refactorización para cambiar el nombre de ese campo sin romper este código
Podría usar la siguiente clase que contiene un método que usa un árbol de expresiones como argumento para determinar un nombre de miembro basado en una expresión lambda:
public class MemberHelper<T>
{
public string GetName<U>(Expression<Func<T, U>> expression)
{
MemberExpression memberExpression = expression.Body as MemberExpression;
if (memberExpression != null)
return memberExpression.Member.Name;
throw new InvalidOperationException("Member expression expected");
}
}
Entonces utilízalo así:
MemberHelper<MyClass> memberHelper = new MemberHelper<MyClass>();
string name = memberHelper.GetName(x => x.MyField);
Si solo desea obtener el nombre de un miembro de la instancia, puede usar un código más corto:
public static string GetMemberName<TValue>(Expression<Func<TValue>> memberAccess)
{
return ((MemberExpression)memberAccess.Body).Member.Name;
}
Y utilízalo como el siguiente dentro de la clase:
ReflectionTools.GetMemberName(() => _someInstanceVariableOrProperty)
Usando Reflection puedes encontrar a todos los miembros de MyClass
con esto.
MemberInfo[] members = typeof(MyClass).GetMembers();
Ahora puedes encontrar la propiedad deseada para cada miembro.
foreach ( MemberInfo memberInfo in members)
{
Console.WriteLine("Name: {0}", memberInfo.Name); // Name: MyField
Console.WriteLine("Member Type: {0}", memberInfo.MemberType); // Member Type: Property
}
Si solo desea buscar Propiedades, utilice PropertyInfo
lugar de MemberInfo
. O escribe esto
foreach ( MemberInfo memberInfo in members.Where(p => p.MemberType == MemberTypes.Property))
{
Console.WriteLine("Name: {0}", memberInfo.Name); // Name: MyField
Console.WriteLine("Member Type: {0}", memberInfo.MemberType); // Member Type: Property
}