Lambda Expression Tree Parsing
-
04-07-2019 - |
Vra
Ek probeer Lambda uitdrukkings in 'n projek om die kaart om 'n derde party navraag API. So, ek ontleding van die Expression boom met die hand.
As ek slaag in 'n lambda uitdrukking soos:
p => p.Title == "title"
alles werk.
As my lambda uitdrukking lyk:
p => p.Title == myaspdropdown.SelectedValue
Die gebruik van die NET debugger, kan ek nie sien die werklike waarde van daardie funciton. In plaas ek sien iets soos:
p => p.Title = (value(ASP.usercontrols_myaspusercontrol_ascx).myaspdropdown.SelectedValue)
Wat gee? En toe ek probeer om die regte kant van die uitdrukking as 'n string gryp, kry ek (value(ASP.usercontrols_myaspusercontrol_ascx).myaspdropdown.SelectedValue)
in plaas van die werklike waarde. Hoe kry ek die werklike waarde?
Oplossing
Onthou dat wanneer jy te doen het met die lambda uitdrukking as 'n uitdrukking boom, wat jy nie uitvoerbare kode het. Eerder jy 'n boom van uitdrukking elemente, waaruit die uitdrukking wat jy geskryf het.
Charlie Calvert het 'n goeie post 'n> wat bespreek hierdie in detail. Ingesluit is 'n voorbeeld van die gebruik van 'n uitdrukking visualiseerder vir ontfouting uitdrukkings.
In jou geval, om die waarde van die regterkant van die uitdrukking gelykheid te kry, wat jy nodig het om 'n nuwe lambda uitdrukking te skep, saam te stel en dan te roep nie.
Ek het saam gekap 'n vinnige voorbeeld hiervan - hoop dit lewer wat jy nodig het
.public class Class1
{
public string Selection { get; set; }
public void Sample()
{
Selection = "Example";
Example<Book, bool>(p => p.Title == Selection);
}
public void Example<T,TResult>(Expression<Func<T,TResult>> exp)
{
BinaryExpression equality = (BinaryExpression)exp.Body;
Debug.Assert(equality.NodeType == ExpressionType.Equal);
// Note that you need to know the type of the rhs of the equality
var accessorExpression = Expression.Lambda<Func<string>>(equality.Right);
Func<string> accessor = accessorExpression.Compile();
var value = accessor();
Debug.Assert(value == Selection);
}
}
public class Book
{
public string Title { get; set; }
}
Ander wenke
Om die werklike waarde kry, moet jy die logika van die uitdrukking boom om alles konteks jy het toe te pas.
Die hele punt van uitdrukking bome is wat hulle verteenwoordig die logika as data, eerder as die evaluering van die uitdrukking. Jy moet uit te werk wat die lambda uitdrukking werklik beteken. Wat kan beteken die evaluering van sommige dele van dit teen plaaslike data - wat jy nodig het om te besluit wat vir jouself. Uitdrukking bome is baie kragtig, maar dit is nie 'n eenvoudige saak om te ontleed en te gebruik. (Vra enigiemand wat geskryf 'n LINQ verskaffer ... Frans Bouma het die probleme 'n paar keer daaroor gekla.)
Just sukkel met dieselfde probleem, dankie Bevan. Op 'n verlengstuk, die volgende is 'n generiese patroon wat jy kan gebruik om die waarde te onttrek (die gebruik van hierdie in my navraag enjin).
[TestFixture]
public class TestClass
{
[Test]
public void TEst()
{
var user = new User {Id = 123};
var idToSearch = user.Id;
var query = Creator.CreateQuery<User>()
.Where(x => x.Id == idToSearch);
}
}
public class Query<T>
{
public Query<T> Where(Expression<Func<T, object>> filter)
{
var rightValue = GenericHelper.GetVariableValue(((BinaryExpression)((UnaryExpression)filter.Body).Operand).Right.Type, ((BinaryExpression)((UnaryExpression)filter.Body).Operand).Right);
Console.WriteLine(rightValue);
return this;
}
}
internal class GenericHelper
{
internal static object GetVariableValue(Type variableType, Expression expression)
{
var targetMethodInfo = typeof(InvokeGeneric).GetMethod("GetVariableValue");
var genericTargetCall = targetMethodInfo.MakeGenericMethod(variableType);
return genericTargetCall.Invoke(new InvokeGeneric(), new[] { expression });
}
}
internal class InvokeGeneric
{
public T GetVariableValue<T>(Expression expression) where T : class
{
var accessorExpression = Expression.Lambda<Func<T>>(expression);
var accessor = accessorExpression.Compile();
return accessor();
}
}
Ek is nie seker ek verstaan. Waar is jy "sien" wat? Is dit by ontwerp-time of hardloop-time? Lambda uitdrukkings kan beskou word hoofsaaklik as anonieme afgevaardigdes, en sal werk met uitgestelde uitvoering. So moet jy nie verwag om die waarde wat tot ná uitvoering daardie lyn geslaag het, natuurlik sien.
Ek dink nie dit is regtig wat jy bedoel maar ... as jy die vraag 'n bietjie miskien is ek kan help verduidelik:)