2017-07-29 4 views
1

Ich möchte eine Eigenschaft an eine Funktion übergeben, so dass die Funktion sowohl den Wert der Eigenschaft als auch den Namen der Eigenschaft kennt. So kann ich Fehler zurückgeben, die den Eigenschaftsnamen entsprechen.C# Übergeben/Abrufen eines Eigenschaftsnamens aus einem Parameter ohne Reflektion

Ich habe derzeit Code wie folgt:

var userNameField = personField.GetChildField(f => f.UserName, nameof(personField.Value.UserName)); 

viele Male wiederholt, so dass der zweite Parameter ist der Name der Eigenschaft innerhalb des Lambda des ersten Parameters ist.

Ist es möglich, diesen Parameter zu automatisieren, so:

  1. Der Duplikat-Code wird
  2. zur Compile-Zeit berechnet wird für jeden Anruf
, nicht zur Laufzeit Der String Name der Eigenschaft gegangen

Idealerweise würde ich meinen Code mag einfach aussehen:

var userNameField = personField.GetChildField(f => f.UserName); 

ich habe habe dies funktioniert unter Verwendung der Reflexion mit Expression<Func..., d. h. ((MemberExpression) getPropertyFunc.Body).Member.Name;, aber das ist zu langsam, insbesondere kompiliert den Ausdruck in eine Funktion, die ich verwenden kann, um den Eigenschaftswert zu holen.

In ähnlicher Weise habe ich hier durch die Ideen zu lesen: Get name of property as a string

Gibt es eine Möglichkeit, die Eigenschaftsnamen bei der Kompilierung von der GetChildField Funktion zu bevölkern? Oder es irgendwie in das Modell codieren?

+0

Wenn der Ausdruck Kompilieren zu langsam ist, haben Sie versucht, das Ergebnis dieser Zusammenstellung das Caching? Es würde den ersten Anruf nicht schneller machen, aber nachfolgende Anrufe könnten davon profitieren. Da Sie anscheinend nur Ausdrücke der Form 'x => x.Property' akzeptieren, haben Sie versucht, die Eigenschaft durch Reflektion zu erhalten, anstatt den Ausdruck zu kompilieren? –

+0

Kann das Ergebnis der Kompilierung zwischengespeichert werden? Ich rufe die Methode auf, die den Ausdruck mit vielen verschiedenen Ausdrücken über die Codebasis kompiliert, so dass sie pro Anruf zwischengespeichert werden müssten. Ihr zweiter Punkt ist jedoch korrekt. Ich habe es geschafft, die Performance zu verbessern, indem ich die Compilation entferne und die Eigenschaft durch Reflektion erhalte, aber es ist immer noch nicht ideal, da der Property-Name zur Laufzeit noch berechnet wird (ich glaube, es sei denn, der Compiler macht etwas Funky). –

Antwort

-1

Nach der Roslyn Dokumentation here der nameof Operator zur Compile-Zeit pro der ersten Zeile unter dem „Semantics“ Abschnitt ausgewertet, die

Der nameof Ausdruck liest eine Konstante ist. In allen Fällen wird nameof (...) zur Kompilierzeit ausgewertet, um einen String zu erzeugen. Sein Argument wird zur Laufzeit nicht ausgewertet und gilt als nicht erreichbarer Code (es wird jedoch keine Warnung "nicht erreichbarer Code" ausgegeben).

0

Es ist möglich, durch folgende:

Item model=new Item();  
var propertyInfo = model.GetType();  
var value=propertyInfo.GetProperty("IrrA").GetValue(model, null).ToString(); 
+0

Hat das OP nicht nach einer Reflexionslösung gefragt? – kuskmen

+0

@kuskmen Eigentlich nein, OP hat nicht nach einer Lösung ohne Reflektion gefragt. OP gab nur an, dass das Kompilieren eines Ausdrucks zu langsam war. Dies könnte schneller sein als das Kompilieren des Ausdrucks (oder nicht - ich habe es nicht getestet). –

+0

Ich fragte nach einer Lösung, die den Eigenschaftsnamen zur Kompilierzeit berechnete, nicht zur Laufzeit. Diese Lösung ist jedoch schneller als das Kompilieren des Ausdrucks. –

Verwandte Themen