2014-12-27 21 views
5

Ich versuche, eine "Property Selector" aus einer Zeichenfolge zu generieren.Erstellen eines Eigenschaftenselektors Ausdruck aus einer Zeichenfolge

Lassen Sie mich ein wenig mit einem Praxisbeispiel erklären:

Wir haben eine Klasse Person mit einem Namen (string) Eigenschaft.

Ich konnte manuell ein „Auswahlmenü“ wie diese propertySelector Schreiben erstellen:

Expression<Func<Person, string>> propertySelector = x => x.Name; 

Aber ich mag das gleiche Auswahlmenü mit meiner Methode erhalten.

var propertySelector = CreatePropertySelectorExpression<Person, string>("Name"); 

Was ich habe, ist so weit dies:

public static Expression<Func<TIn, TOut>> CreatePropertySelectorExpression<TIn, TOut>(string path) 
{ 
    Expression exp = Expression.Parameter(typeof(TIn), "x"); 
    foreach (var property in path.Split('.')) 
    { 
     exp = Expression.PropertyOrField(exp, property); 
    } 
    return exp; 
} 

Aber ... ich habe und ungültige Gussfehler!

kann nicht implizit Typ 'System.Linq.Expressions.Expression' zu 'System.Linq.Expressions.Expression>' konvertieren. Eine explizite Konvertierung vorhanden ist (möglicherweise fehlt eine Guss?)

Ich bin sehr neu für Ausdrücke und ich weiß nicht, wie :(

+0

bitte könnten Sie ein echtes Beispiel für die Verwendung hinzufügen? – InferOn

+0

Es gibt einige Fehler in Ihrem Code, zum Beispiel Expression.Parameter wird ParameterExpression zurückgeben, Expression.PropertyOrField wird MemberExpression zurückgeben, aufrichtig verstehe ich nicht, was Sie erreichen würden – InferOn

+0

Bitte überprüfen Sie die Bearbeitung, die ich gerade gemacht habe. Ich gebe ein viel besseres Beispiel. Vielleicht ist der Code falsch. Ich bin ein Neuling in Bezug auf Ausdrücke :(Vielen Dank im Voraus! – SuperJMN

Antwort

12

Ihre exp enthält nur den Körper des Lambda fortzusetzen . Aber Sie wollen eine tatsächliche Lambda-Funktion, die TIn dort einen Parameter vom Typ nimmt So haben Sie eine Lambda mit Expression.Lambda erstellen müssen.. wenn

var param = Expression.Parameter(typeof(TIn)); 
var body = Expression.PropertyOrField(param, propertyName); 
return Expression.Lambda<Func<TIn, TOut>>(body, param); 

Beachten Sie, dass der Ausdruck helfen Ihnen nicht wirklich viel Sie wollen wahrscheinlich ein kompiliert fu nction statt:

private static Func<TIn, TOut> CreatePropertyAccessor<TIn, TOut> (string propertyName) 
{ 
    var param = Expression.Parameter(typeof(TIn)); 
    var body = Expression.PropertyOrField(param, propertyName); 
    return Expression.Lambda<Func<TIn, TOut>>(body, param).Compile(); 
} 

Anschließend können Sie es wie folgt verwendet werden:

var name1 = CreatePropertyAccessor<Obj, string>("Name"); 
var name2 = CreatePropertyAccessor<Obj, string>("Name2"); 
var name3 = CreatePropertyAccessor<Obj, string>("Name3"); 

var o = new Obj() // Obj is a type with those three properties 
{ 
    Name = "foo", 
    Name2 = "bar", 
    Name3 = "baz" 
}; 

Console.WriteLine(name1(o)); // "foo" 
Console.WriteLine(name2(o)); // "bar" 
Console.WriteLine(name3(o)); // "baz" 
+0

Nur wow !! Works! Vielen Dank! – SuperJMN

Verwandte Themen