This is my class:
class SampleExpression
{
public static void SampleEnum(IEnumerator<string> ien)
{
while (ien.MoveNext())
{
Console.WriteLine(ien.Current);
}
}
}
This is how i am trying to invoke the SampleEnum
method:
public void Main(string[] args)
{
ParameterExpression param2 = Expression.Parameter(typeof(SampleExpression), "args");
var lstConstant = "1,2,3,4,".Split(new string[] { "," },
StringSplitOptions.RemoveEmptyEntries).ToList();
Expression ep = Expression.Constant(Expression.Constant(lstConstant, typeof(IEnumerable<string>)));
var enummethod = typeof(SampleExpression).GetMethod("SampleEnum");
MethodCallExpression methodCall = Expression.Call
(
enummethod
, ep
);
var e = Expression.Lambda<Func<IEnumerator<string>, string>>(methodCall, param2);
e.Compile()(lstConstant.GetEnumerator());
}
I get the following error in the line which tries to create the method call expression:
Expression of type 'System.Linq.Expressions.TypedConstantExpression' cannot be used for parameter of type 'System.Collections.Generic.IEnumerator
1[System.String]' of method 'Void Enum(System.Collections.Generic.IEnumerator
1[System.String])'
Please help.
You seem to be very confused - it might help to have a look at how the C# compiler would generate a similar expression tree. In any case, there's a few mistakes you've made:
IEnumerable<T>
isn't IEnumerator<T>
. They're not interchangeable.param2
is a parameter expression that takes SampleExpression
, while your lambda actually expects IEnumerator<string>
.ep
is a constant expression of a constant expression. That's not what you want. Remove the outer Expression.Constant
.Func<string>
instead of Func<IEnumerator<string>, string>
.string
.Assuming you want to have a lambda that takes IEnumerator<string>
and uses it to call SampleExpression.SampleEnum
, you could use something like this:
public void Test()
{
var enumeratorParameter
= Expression.Parameter(typeof(IEnumerator<string>), "enumerator");
var sampleEnumMethod = typeof(SampleExpression).GetMethod("SampleEnum");
var methodCall = Expression.Call(sampleEnumMethod, enumeratorParameter);
var e = Expression.Lambda<Func<IEnumerator<string>, string>>
(
methodCall,
enumeratorParameter
);
var lstConstant = "1,2,3,4,".Split(',');
e.Compile()(lstConstant.ToList().GetEnumerator());
}
class SampleExpression
{
public static string SampleEnum(IEnumerator<string> ien)
{
while (ien.MoveNext())
{
Console.WriteLine(ien.Current);
}
return "Done!";
}
}