(Siehe unten stehende Lösung, die ich mit der von mir akzeptierten Antwort erstellt habe.)
Ich versuche, die Wartbarkeit von Code mit Reflexion zu verbessern. Die App verfügt über eine .NET Remoting-Oberfläche, die unter anderem eine Methode namens Execute für den Zugriff auf Teile der App bereitstellt, die nicht in der veröffentlichten Remote-Oberfläche enthalten sind.
So bestimmt die App Eigenschaften (in diesem Beispiel eine statische), auf die über Execute zugegriffen werden soll:
RemoteMgr.ExposeProperty("SomeSecret", typeof(SomeClass), "SomeProperty");
Ein entfernter Benutzer könnte also anrufen:
string response = remoteObject.Execute("SomeSecret");
und die App würde Reflection verwenden, um SomeClass.SomeProperty zu finden und seinen Wert als Zeichenfolge zurückzugeben.
Wenn jemand SomeProperty umbenennt und vergisst, den 3. Parameter von ExposeProperty () zu ändern, wird dieser Mechanismus leider unterbrochen.
Ich muss das Äquivalent von:
SomeClass.SomeProperty.GetTheNameOfThisPropertyAsAString()
Als 3. Parameter in ExposeProperty zu verwenden, damit Refactoring-Tools das Umbenennen übernehmen.
Gibt es eine Möglichkeit, dies zu tun? Danke im Voraus.
Okay, hier ist, was ich letztendlich erstellt habe (basierend auf der Antwort, die ich ausgewählt habe, und der Frage, auf die er verwiesen hat):
// <summary>
// Get the name of a static or instance property from a property access lambda.
// </summary>
// <typeparam name="T">Type of the property</typeparam>
// <param name="propertyLambda">lambda expression of the form: '() => Class.Property' or '() => object.Property'</param>
// <returns>The name of the property</returns>
public string GetPropertyName<T>(Expression<Func<T>> propertyLambda)
{
var me = propertyLambda.Body as MemberExpression;
if (me == null)
{
throw new ArgumentException("You must pass a lambda of the form: '() => Class.Property' or '() => object.Property'");
}
return me.Member.Name;
}
Verwendung:
// Static Property
string name = GetPropertyName(() => SomeClass.SomeProperty);
// Instance Property
string name = GetPropertyName(() => someObject.SomeProperty);
Mit dieser coolen Funktion ist es jetzt an der Zeit, die ExposeProperty-Methode zu vereinfachen. Das Polieren von Türklinken ist eine gefährliche Arbeit ...
Vielen Dank an alle.
quelle
Antworten:
Verwenden von GetMemberInfo von hier aus: Wenn Sie den Eigenschaftsnamen aus dem Lambda-Ausdruck abrufen , können Sie Folgendes tun:
RemoteMgr.ExposeProperty(() => SomeClass.SomeProperty)
quelle
GetMemberInfo
? Ich kann mit dem Paket "Common Utilities" für die Microsoft Enterprise Library nichts finden. MSDN scheint darauf hinzuweisen, dass es diese Methode enthält. Es gibt ein "inoffizielles" Paket, aber inoffiziell zu sein ist nicht inspirierend. Die Antwort von JimC , die auf dieser basiert, ist viel prägnanter und basiert nicht auf einer scheinbar nicht verfügbaren Bibliothek.Mit C # 6.0 ist dies jetzt kein Problem mehr, wie Sie es tun können:
Dieser Ausdruck wird zur Kompilierungszeit in aufgelöst
"SomeProperty"
.MSDN-Dokumentation von nameof .
quelle
const string
! ErstaunlichRaiseProperty
in WPF wollen! Verwenden Sie RaisePropertyChanged (nameof (Eigenschaft)) anstelle von RaisePropertyChanged ("Eigenschaft")Es gibt einen bekannten Hack, um ihn aus dem Lambda-Ausdruck zu extrahieren (dies ist aus der PropertyObserver-Klasse von Josh Smith in seiner MVVM-Stiftung):
Entschuldigung, hier fehlte ein Kontext. Dies war Teil einer größeren Klasse, in der
TPropertySource
sich die Klasse befindet, die die Eigenschaft enthält. Sie können die Funktion in TPropertySource generisch machen, um sie aus der Klasse zu extrahieren. Ich empfehle, sich den vollständigen Code der MVVM Foundation anzusehen .quelle
public static string GetPropertyName<TPropertySource>(Expression<Func<TPropertySource, object>> expression)
var name = GetPropertyName<TestClass>(x => x.Foo);
Okay, hier ist, was ich letztendlich erstellt habe (basierend auf der Antwort, die ich ausgewählt habe, und der Frage, auf die er verwiesen hat):
Verwendung:
quelle
Die PropertyInfo- Klasse soll Ihnen dabei helfen, wenn ich das richtig verstehe.
Type.GetProperties () -Methode
Ist das was du brauchst?
quelle
Mit Reflection können Sie die tatsächlichen Namen der Eigenschaften abrufen.
http://www.csharp-examples.net/reflection-property-names/
Wenn Sie einer Eigenschaft einen "String-Namen" zuweisen möchten, schreiben Sie ein Attribut, über das Sie nachdenken können, um den String-Namen zu erhalten.
quelle
Ich habe Ihre Lösung so geändert, dass sie mehrere Eigenschaften verkettet:
Verwendung:
quelle
Basierend auf der Antwort, die bereits in der Frage und in diesem Artikel enthalten ist: https://handcraftsman.wordpress.com/2008/11/11/how-to-get-c-property-names-without-magic-strings/ I. präsentiere meine Lösung für dieses Problem:
Und ein Test, der auch die Verwendung zum Beispiel und statische Eigenschaften zeigt:
quelle
Alte Frage, aber eine andere Antwort auf diese Frage besteht darin, eine statische Funktion in einer Hilfsklasse zu erstellen, die das CallerMemberNameAttribute verwendet.
Und dann benutze es wie:
quelle
Sie können die StackTrace-Klasse verwenden, um den Namen der aktuellen Funktion abzurufen (oder wenn Sie den Code in eine Funktion einfügen, eine Ebene zurücktreten und die aufrufende Funktion abrufen).
Siehe http://msdn.microsoft.com/en-us/library/system.diagnostics.stacktrace(VS.71).aspx
quelle
Ich habe diese Antwort mit großer Wirkung verwendet: Holen Sie sich die Eigenschaft als Zeichenfolge aus einem Ausdruck <Func <TModel, TProperty >>
Mir ist klar, dass ich diese Frage bereits vor einiger Zeit beantwortet habe. Der einzige Vorteil meiner anderen Antwort ist, dass sie für statische Eigenschaften funktioniert. Ich finde die Syntax in dieser Antwort viel nützlicher, da Sie keine Variable des Typs erstellen müssen, den Sie widerspiegeln möchten.
quelle
Ich hatte einige Schwierigkeiten, die bereits für meinen speziellen Anwendungsfall vorgeschlagenen Lösungen zu verwenden, fand es aber schließlich heraus. Ich denke nicht, dass mein spezieller Fall eine neue Frage wert ist, deshalb veröffentliche ich meine Lösung hier als Referenz. (Dies hängt sehr eng mit der Frage zusammen und bietet eine Lösung für alle anderen, die einen ähnlichen Fall wie ich haben.)
Der Code, den ich erhalten habe, sieht folgendermaßen aus:
Der wichtige Teil für mich ist, dass
CompanyControl
der Compiler mir in der Klasse nur erlaubt, eine boolesche Eigenschaft auszuwählenICompanyViewModel
, die es anderen Entwicklern erleichtert, sie richtig zu machen.Der Hauptunterschied zwischen meiner Lösung und der akzeptierten Antwort besteht darin, dass meine Klasse generisch ist und ich nur Eigenschaften des generischen Typs abgleichen möchte, die boolesch sind.
quelle
So habe ich es implementiert. Der Grund dafür ist, dass wenn die Klasse, von der Sie den Namen von ihrem Mitglied erhalten möchten, nicht statisch ist, Sie einen Instanse davon erstellen und dann den Namen des Mitglieds erhalten müssen. so generisch kommt hier um zu helfen
Die Verwendung ist wie folgt
quelle