Reputation: 11474
I have seen a number of similar posts and it seems as though the var1 I have declared seems to need to be passed in elsewhere, but I can't seem to figure it out.
public Expression<Func<ElementNode, bool>> CreateEqualNameExpression(string match)
{
var parm = Expression.Parameter(typeof(ElementNode), "element");
var expr = Expression.Call(parm, typeof(ElementNode).GetProperty("Name").GetGetMethod());
var var1 = Expression.Variable(typeof(string), "elementName");
var assign = Expression.Assign(var1, expr);
var parm2 = Expression.Constant(match, typeof(string));
var exp = Expression.Equal(assign, parm2);
return Expression.Lambda<Func<ElementNode, bool>>(exp, new[] { parm });
}
basically I'm trying to create a method that represents
(ElementNode ele) => ele.Name == match;
but I'm having a really hard time coming up with the solution. Any help would be greatly appreciated.
I'm getting the error: 'elementName' of type 'System.STring' referenced from scope'', but it is not defined.
Upvotes: 1
Views: 833
Reputation: 14370
As svick said, there's no need for the assignment:
public Expression<Func<ElementNode, bool>> CreateEqualNameExpression(string match)
{
var parmExpr = Expression.Parameter(typeof(ElementNode));
var propertyExpr = Expression.Property(parmExpr, "Name");
var constExpr = Expression.Constant(match, typeof(string));
var isEqualExp = Expression.Equal(propertyExpr, constExpr);
return Expression.Lambda<Func<ElementNode, bool>>(isEqualExp , new[] { parmExpr });
}
Upvotes: 1
Reputation: 25623
As others have said, you do not actually need the intermediate variable, but seeing as you're trying to learn about expression trees, it's good information to know.
Local variables must be declared within a BlockExpression
:
public Expression<Func<ElementNode, bool>> CreateEqualNameExpression(string match)
{
var parm = Expression.Parameter(typeof(ElementNode), "element");
var expr = Expression.Property(parm, "Name");
var var1 = Expression.Variable(typeof(string), "elementName");
var assign = Expression.Assign(var1, expr);
var parm2 = Expression.Constant(match, typeof(string));
var exp = Expression.Equal(var1, parm2);
return Expression.Lambda<Func<ElementNode, bool>>(
Expression.Block(new[] { var1 }, assign, exp),
parm);
}
Which approximately creates:
element => { var elementName = element.Name; return elementName == <constant>; }
Note that I used the Property
method to build a property accessor rather than using Call
. This is the preferred way of accessing properties, unless the property is non-public.
Upvotes: 3
Reputation: 2542
Do you want the disgustingly easy version?
Expression.Lambda<Func<ElementNode, bool>> func = elem => elem.Name == match;
.Net will build the expression tree for you.
By the way, the code has a fault, it should be comparing var1 against the match (parm2), not 'assign'
var exp = Expression.Equal(var1, parm2);
Upvotes: 2