2016-06-28 2 views
1

Ich habe früher Methoden geschaffen, das eine Eigenschaft als Eingabe mit folgenden Syntax nehmen:Property Ausdruck in der Klasse Konstruktor, oder als Eigentum

public void MyMethod<T>(Expression<Func<T>> property) { } 

public int MyProperty { get; set; } 

public void SomeOtherMethod() { 
    MyMethod(() => MyProperty); 
} 

Auf diese Weise kann ich zum Beispiel warf die Eigenschaft auf einem MemberExpression und erhalten Sie den voll qualifizierten Namen der Eigenschaft.

Ist es jedoch möglich, das gleiche in einem Klassenkonstruktor zu tun, oder eine Eigenschaft, die eine andere Eigenschaft speichert, wie die property Variable in MyMethod() tut?

Ich habe Folgendes versucht, aber das hat nicht funktioniert, weil der Typ Parameter in beiden Fällen nicht angegeben ist, aber ich würde nicht einmal wissen, welchen Typ zu verwenden ... vor allem, weil der Typ magisch in der abgeleitet wird oberstes Beispiel.

Im Konstruktor

public class MyClass<T> { 
    public MyClass(Expression<Func<T>> property) { } 
} 

public int MyProperty { get; set; } 

var myClass = new MyClass(() => MyProperty); 

Als Eigenschaft

public class MyClass<T> { 
    public Expression<Func<T>> SomeProperty { get; set; } 
} 

public int MyProperty { get; set; } 

var myClass = new MyClass() { SomeProperty =() => MyProperty }; 

Also, wie kann ich eine Unterkunft Ausdruck in einem Konstruktor oder Eigentum seiner eigenen haben, ohne die Verwendung der Typdefinition mit ?

Antwort

1

Kann man in einem Klassenkonstruktor [generische Parameter ableiten]?

In C# generic inference is not supported on constructors, so haben Sie es explizit setzen:

var myClass = new MyClass<int>(() => MyProperty); 

Der Hauptgrund, es nicht unterstützt wird ist, weil es oft viele-Typen, die als generische Einschränkung verwendet werden könnten, aufgrund Implizite Typkonvertierungen, so dass der Compiler die "besten" generischen Parameter basierend auf den Informationen wählen müsste, die er hat. Die mit dem Entwerfen, Programmieren, Testen, Dokumentieren und Integrieren dieser Logik verbundenen Kosten überwiegen den Nutzen oder bieten zumindest keinen relativen Vorteil, der die anderen Funktionen übertrifft, die MS für die Entwicklung von Zeit benötigt. In diesem Fall kennen Sie den besten generischen Parametertyp, da die MyProperty-Eigenschaft einen int zurückgibt. Technisch könnten Sie jeden Typ verwenden, der implizit von int (object, double usw.) umwandelbar ist, aber int ist die beste Anpassung.

Könnte ich vielleicht Objekt als Catch-All verwenden?

Sicher, aber dann ist Ihr Code nicht generisch. Sie können nur tun

public class MyClass { 
    public MyClass(Expression<Func<object>> property) { } 
} 
+0

Das ist eine Schande, weil ich gehofft hatte, diese Syntax als eine generische für alle Arten von Eigenschaften verwenden zu können. Die Eigenschaften können alle Arten von Typen sein (string, int, double, benutzerdefinierte Klassen). Könnte ich 'object' vielleicht als Catch-All verwenden, weil der Typ an sich nicht so interessant ist, aber die' MemberExpression' der Eigenschaft ist? – GTHvidsten

+0

Es hängt davon ab, was sonst 'MyClass' mit dem generischen Typ _does_. Wenn Sie nur "Objekt" verwenden, sehe ich nicht, warum Sie Generika überhaupt brauchen. Sie können einfach 'öffentliche Klasse MyClass { öffentliche MyClass (Ausdruck > Eigenschaft) {} }' –

+0

Für den spezifischen Anwendungsfall, den ich jetzt entwickle, Hardcoding der Typ zu vermeiden, Generika lösen alle meine Probleme. Ich halte nicht den Atem an MS, um es in C# -47 zu implementieren;) Danke für die Klarstellung! – GTHvidsten

0

Sie müssen den Typ-Parameter von T

var myClass = new MyClass<int>(() => MyProperty); 

var myClass = new MyClass<int>() { SomeProperty =() => MyProperty }; 

sonst wird es nicht wissen, liefern, welche Art des Ausdrucks es im Konstruktor bekommen sollte.

Verwandte Themen