2010-09-07 4 views
38

C'è tutta una ricchezza di esempi di riflessione là fuori che ti permettono di ottenere uno:Ottiene il nome di stringa della proprietà utilizzando la riflessione

    1. Tutte le proprietà in una classe

    2. Una singola proprietà, a condizione si conosce il nome della stringa

c'è un modo (utilizzando la riflessione, TypeDescriptor, o altro) per ottenere il nome della stringa di una proprietà in una classe in fase di esecuzione, purché tutto quello che ho è un'istanza della classe e della proprietà ?

EDIT So che posso ottenere facilmente tutte le proprietà in una classe utilizzando la riflessione e quindi ottenere il nome di ciascuna proprietà. Quello che sto chiedendo è una funzione per darmi il nome di una proprietà, a condizione che io passi l'istanza della proprietà. In altre parole, come trovo la proprietà che voglio dall'array PropertyInfo [] restituita da class.GetType(). GetProperty (myProperty) in modo che possa ottenere PropertyInfo.Name da esso?

+3

Vuoi dire ottenere il nome di una proprietà all'interno del getter/setter della proprietà? Cosa intendi per "avere" una proprietà? – Jacob

+1

@Jacob - Per aggiungere un po 'di chiarezza, ho un'istanza della classe con la proprietà (così come altre proprietà) che voglio ottenere il nome della stringa (non il getter/setter). Ho bisogno di fare un po 'di lavoro su quella proprietà usando Reflection, ma non voglio mantenere il codice con i nomi delle stringhe hardcoded nel caso in cui io rifatti il ​​nome della proprietà. Quindi, voglio ottenere in modo programmatico il nome della proprietà. –

+1

In quale altro modo si può identificare la proprietà che si desidera, se non per nome? – jnylen

risposta

81

Se si dispone già di uno PropertyInfo, la risposta di @ dtb è quella giusta. Se, tuttavia, stai cercando il codice della proprietà in cui ti trovi attualmente, dovrai attraversare lo stack di chiamate corrente per scoprire quale metodo stai correntemente eseguendo e ottenere il nome della proprietà da lì.

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

Edit:

Dopo il chiarimento, mi chiedo se quello che hai intenzione di fare è ottenere il nome di una proprietà da una proprietà espressione. Se è così, si potrebbe desiderare di scrivere un metodo come questo:

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

Per usarlo, devi scrivere qualcosa di simile:

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

+1 per l'uso di Espressione; Non ho capito la domanda in questo modo. –

+0

+1 per l'espressione. Stavo diventando Dead Crazy con quello! Molte molte grazie, amico ... (A proposito, se potessi spiegarmi un po 'la sintassi C#, perché questo suona cose abbastanza avanzate, devo ammettere che non ho capito tutto, anche se funziona come un fascino) –

+1

La sintassi è un po 'bizzarra. La sintassi per le espressioni è proprio come la sintassi per le espressioni lambda; se è uno o l'altro dipende dal tipo di parametro nel metodo che viene chiamato. Se '() => myObject.AProperty' era un'espressione lambda in cui AProperty era di tipo' int', il suo tipo si traduce fondamentalmente in "un metodo senza parametri'() 'che restituisce' => 'an' int' (implicitamente determinato attraverso la tipizzazione statica), che è equivalente a 'Func '. Poiché 'GetPropertyName' prende un' Expression', il tipo del parametro si traduce in 'Expression >' – Jacob

0

myClassInstance.GetType().GetProperties() ti dà PropertyInfo istanze per tutte le proprietà pubbliche per il tipo di myClassInstance s'. (Vedere MSDN per documentazione e altri sovraccarichi.)'PropertyInfo.Name' è il nome effettivo della proprietà. Se conosci già il nome della proprietà, utilizza GetProperty(name) per recuperare l'oggetto PropertyInfo (vedi di nuovo MSDN).

5

Nel caso qualcuno ne ha bisogno ... ecco il versione VB .NET della risposta:

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 

Usage:

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

Grazie TKTS, la tua risposta è grande, e questo è il codice C# di questa sintassi stringa statica pubblica getPropertyName (Espressione > PropertyExp) { \t return (Pro pertyExp.Body as MemberExpression) .Member.Name; } string name = GetPropertyName (() => (new Tasks()). Title); –

0

Ho usato la versione fornita da Jacob ma a volte ha dato un'eccezione. Era perché il cast non era valido.Questa versione ha risolto il 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 risposta giusta, che è stato scritto da TKTS, e qui voglio solo di convertire la sua sintassi per C#

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

e l'utilizzo di questo codice va come il esempio come segue:

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

inoltre: c'è un'eccezione potrebbe essere accadere che quando il viene fornito con tutte le proprietà presenta valori nulli, così nessuno deve prendere questo su sua concentrazione quando hes attuare il suo codice

Grazie TKTS ..

37

Con C# 6.0 (Visual Studio 2015), è ora possibile utilizzare l'operatore nameof, in questo modo:

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

Questo è un metodo davvero eccezionale. – Gandalf458