Reputation: 1963
This is my class
class SampleExpression
{
public string str;
public static bool SampleEnum(SampleExpression s, IEnumerator<string> ien = null)
{
while (ien.MoveNext())
{
if (s.str == ien.Current)
{
ien.Reset();
return true;
}
}
return false;
}
}
This is how i am generating my expression tree at runtime:
static void Main(string[] args)
{
ParameterExpression param1 = Expression.Parameter(typeof(SampleExpression), "token");
ParameterExpression param2 = Expression.Parameter(typeof(IEnumerator<string>), "args");
var lstConstant = "1,2,3,4,".Split(new string[] { "," },
StringSplitOptions.RemoveEmptyEntries).ToList();
var enummethod = typeof(SampleExpression).GetMethod("SampleEnum");
MethodCallExpression methodCall = Expression.Call
(
enummethod,
param1
, param2
);
var e = Expression.Lambda<Func<SampleExpression, IEnumerator<string>, bool>>(methodCall, param1, param2);
var l = e.Compile();
List<SampleExpression> lst = new List<SampleExpression>();
lst.Add(new SampleExpression { str = "1" }); // matches with lstConstant
lst.Add(new SampleExpression { str = "2" }); // matches with lstConstant
lst.Add(new SampleExpression { str = "5" });
var items = lst.Where(x => l(x, lstConstant.GetEnumerator())).ToList();
}
Now i might i have done this in a convoluted way(cause i am novice in Expression trees) - my requirement is this:
I have a comma separated string like this "1,2,3,4,"
. I want to split and match each SampleExpression
with the string parameter str
of the class SampleExpression
. Which i have done so far.
However i want the Expression as Func<SampleExpression,bool>
. As you can see currently its Func<SampleExpression, IEnumerator<string>, bool>
.
How do i fix this.
Upvotes: 0
Views: 311
Reputation: 412
The expression compilation seems weird to me too, but to actually answer your question...
You can wrap the compiled Func like so:
Func<SampleExpression, bool> lBind = (SampleExpression token) => l(token, lstConstant.GetEnumerator());
This binds the enumerator as the second parameter, while leaving the first open for your input.
Upvotes: 2
Reputation: 156459
It's not clear to me why you're doing dynamic expression compilation, so I'm just going to focus on your problem statement:
I have a comma separated string like this
"1,2,3,4,"
. I want to split and match eachSampleExpression
with the string parameterstr
of the classSampleExpression
.
LINQ actually provides a pretty easy way to handle this:
var lstConstant = "1,2,3,4,".Split(new string[] { "," },
StringSplitOptions.RemoveEmptyEntries).ToList();
List<SampleExpression> lst = new List<SampleExpression>();
lst.Add(new SampleExpression { str = "1" }); // matches with lstConstant
lst.Add(new SampleExpression { str = "2" }); // matches with lstConstant
lst.Add(new SampleExpression { str = "5" });
var items = lst.Where(x => lstConstant.Contains(x.str)).ToList();
If you want to have this logic reside in the SampleExpression
class, that's fine:
class SampleExpression
{
public string str;
public static bool SampleEnum(SampleExpression s, IEnumerable<string> ien)
{
return ien.Contains(s.str);
}
}
// Usage:
var items = lst.Where(x => SampleExpression.SampleEnum(x, lstConstant))
.ToList();
If you want the SampleEnum
method itself to return the value to pass into the Where
clause, you can do this instead:
class SampleExpression
{
public string str;
public static Func<SampleExpression, bool> SampleEnum(IEnumerable<string> ien)
{
return s => ien.Contains(s.str);
}
}
// Usage:
var items = lst.Where(SampleExpression.SampleEnum(lstConstant))
.ToList();
Upvotes: 1