2014-12-27 22 views
5

Próbuję wygenerować "Selektor właściwości" z ciągu.Tworzenie selektora właściwości Wyrażenie z ciągu znaków

Pozwól mi wyjaśnić sobie trochę z prawdziwym przykładem życia:

Mamy klasy osoba z nazwą (string) nieruchomości.

mogę ręcznie utworzyć „selektora właściwość” jak to pisze propertySelector:

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

Ale chciałbym, aby uzyskać ten sam wybierak działce z moim sposobem.

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

Co mam tak daleko jest taka:

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

Ale ... mam i błędów obsada nieważny!

nie można niejawnie przekonwertować typu '' do System.Linq.Expressions.Expression 'System.Linq.Expressions.Expression>'. jednoznaczne przekształcenie istnieje (czy brakuje obsady?)

Jestem bardzo nowe do wyrażenia i nie wiem jak dalej :(

+0

proszę można dodać prawdziwy przykład zastosowania? – InferOn

+0

Występuje błąd w kodzie, na przykład Expression.Parameter zwróci ParameterExpression, Expression.PropertyOrField zwróci MemberExpression, szczerze nie rozumiem, co byś uzyskał – InferOn

+0

Proszę, sprawdź edytowaną właśnie edycję. Podaję o wiele lepszy przykład. Może kod jest błędny. Jestem początkującym odnośnie Wyrażeń :(Z góry dzięki! – SuperJMN

Odpowiedz

12

Twój exp zawiera tylko ciało lambda . Ale chcesz rzeczywistą funkcję lambda, która przyjmuje parametr typu TIn tam więc trzeba stworzyć lambda stosując Expression.Lambda:..

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

Zauważ jednak, że wyrażenie nie naprawdę pomóc znacznie prawdopodobnie chcą skompilowany fu nction zamiast:

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

Można następnie używać go tak:

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

Po prostu wow! Działa! Dziękuję! – SuperJMN

Powiązane problemy