2010-09-07 9 views
38

Hay toda una gran cantidad de ejemplos de reflexión por ahí que le permiten obtener ya sea:Obtener nombre de la cadena de establecimiento a través de la reflexión

    1. Todas las propiedades en una clase

    2. Una sola propiedad, siempre se conoce el nombre de la cadena

¿hay alguna manera (utilizando la reflexión, TypeDescriptor, o de otra manera) para obtener el nombre de la cadena de una propiedad en una clase en tiempo de ejecución, siempre todo lo que tengo es una instancia de la clase y la propiedad ?

EDIT Sé que puedo obtener fácilmente todas las propiedades de una clase utilizando la reflexión y luego obtener el nombre de cada propiedad. Lo que estoy pidiendo es una función para darme el nombre de una propiedad, siempre que le pase la instancia de la propiedad. En otras palabras, ¿cómo puedo encontrar la propiedad que quiero de la matriz PropertyInfo [] devuelta desde la clase.GetType(). GetProperty (myProperty) para que pueda obtener PropertyInfo.Name de ella?

+3

¿Quieres decir obtener el nombre de una propiedad dentro del getter/setter de la propiedad? ¿Qué quieres decir con que "tienes" una propiedad? – Jacob

+1

@Jacob: para agregar algo de claridad, tengo una instancia de la clase con la propiedad (así como otras propiedades) de la que quiero obtener el nombre de la cadena (no el getter/setter). Necesito hacer algún trabajo en esa propiedad usando Reflection, pero no quiero mantener el código con nombres de cadena codificados en caso de que refactorice el nombre de la propiedad. Por lo tanto, quiero obtener programáticamente el nombre de la propiedad. –

+1

¿De qué otro modo puede identificar la propiedad que desea, si no es por su nombre? – jnylen

Respuesta

81

Si ya tiene un PropertyInfo, la respuesta de @dtb es la correcta. Sin embargo, si quiere saber en qué código de propiedad se encuentra actualmente, deberá atravesar la pila de llamadas actual para averiguar qué método está ejecutando actualmente y derivar el nombre de la propiedad desde allí.

var stackTrace = new StackTrace(); 
var frames = stackTrace.GetFrames(); 
var thisFrame = frames[0]; 
var method = thisFrame.GetMethod(); 
var methodName = method.Name; // Should be get_* or set_* 
var propertyName = method.Name.Substring(4); 

Editar:

Después de su aclaración, me pregunto si lo que está queriendo hacer es obtener el nombre de una propiedad de una propiedad expresión. Si es así, es posible que desee escribir un método como este:

public static string GetPropertyName<T>(Expression<Func<T>> propertyExpression) 
{ 
    return (propertyExpression.Body as MemberExpression).Member.Name; 
} 

Para usarlo, que iba a escribir algo como esto:

var propertyName = GetPropertyName(
    () => myObject.AProperty); // returns "AProperty" 
+0

+1 para el uso de Expresión; No entendí la pregunta de esta manera. –

+0

+1 para la expresión. ¡Me estaba volviendo loco de muerte con eso! Muchas gracias, amigo ... (Por cierto, si pudieran explicarme un poco la sintaxis C#, porque esto suena bastante avanzado, debo admitir que realmente no lo entendí todo, aunque funciona como un amuleto) –

+1

La sintaxis es un poco extraña. La sintaxis para expresiones es como la sintaxis para expresiones lambda; si es uno u otro depende del tipo de parámetro en el método que se llama. Si '() => myObject.AProperty' era una expresión lambda donde AProperty era del tipo' int', su tipo básicamente se traduce como "un método sin parámetros'() 'que devuelve' => 'an' int' (implícitamente) determinado a través del tipado estático), que es equivalente a 'Func '. Dado que 'GetPropertyName' toma' Expression', el tipo del parámetro se traduce a 'Expresión >' en su lugar. – Jacob

0

myClassInstance.GetType().GetProperties() le da PropertyInfo instancias para todas las propiedades públicas para myClassInstance 's tipo. (Consulte MSDN para documentación y otras sobrecargas).'PropertyInfo.Name 'es el nombre real de la propiedad. En caso de que ya conozca el nombre de la propiedad, use GetProperty(name) para recuperar su objeto PropertyInfo (consulte MSDN nuevamente).

5

En caso de que alguien lo necesita ... Aquí está el VB .NET versión de la respuesta:

Public Shared Function GetPropertyName(Of t)(ByVal PropertyExp As Expression(Of Func(Of t))) As String 
    Return TryCast(PropertyExp.Body, MemberExpression).Member.Name 
End Function 

Uso:

Dim name As String = GetPropertyName(Function() (New myObject).AProperty) 
+0

Gracias TKTS, su respuesta es grande, y este es el código C# de esta sintaxis public static string getPropertyName (Expresión > PropertyExp) { \t return (Pro pertyExp.Body como MemberExpression) .Member.Name; } string name = GetPropertyName (() => (new Tasks()). Title); –

0

Usé la versión provista por Jacob pero a veces daba una excepción. Fue porque el elenco no era válido.Esta versión soluciona el problema:

public static string GetPropertyName<T>(this Expression<Func<T>> propertyExpression) 
    { 
     ConstantExpression cExpr = propertyExpression.Body as ConstantExpression; 
     MemberExpression mExpr = propertyExpression.Body as MemberExpression; 

     if (cExpr != null) 
      return cExpr.Value.ToString(); 
     else if (mExpr != null) 
      return mExpr.Member.Name; 

     else return null; 
    } 
3

acutully la respuesta correcta que está escrito por TKTS, y aquí sólo quiero convertir su sintaxis de C#

public static string GetPropertyName<t>(Expression<Func<t>> PropertyExp) 
{ 
return (PropertyExp.Body as MemberExpression).Member.Name; 
} 

y el uso de este código va como el ejemplo de la siguiente manera:

string name = GetPropertyName(() => (new Tasks()).Title); 

además: hay una excepción podría suceder que cuando el viene con todas las propiedades tiene valores nulos, por lo que nadie tiene que tomar esto en su concentración cuando hes la implementación de su código

, gracias TKTS ..

37

con C# 6.0 (Visual Studio 2015), ahora se puede utilizar el operador nameof, así:

var obj = new MyObject(); 
string propertyName = nameof(obj.Property); 
string methodName = nameof(obj.Method); 
string directPropertyName = nameof(MyObject.Property); 
string directMethodName = nameof(MyObject.Method); 
+1

Este es un método realmente genial. – Gandalf458

Cuestiones relacionadas