无法将 IEnumerable<string> 作为 Expression.Call 中的参数传递
Unable to pass IEnumerable<string> as parameter in Expression.Call
这是我的 class:
class SampleExpression
{
public static void SampleEnum(IEnumerator<string> ien)
{
while (ien.MoveNext())
{
Console.WriteLine(ien.Current);
}
}
}
这就是我尝试调用 SampleEnum
方法的方式:
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());
}
我在尝试创建方法调用表达式的行中收到以下错误:
Expression of type 'System.Linq.Expressions.TypedConstantExpression' cannot be used for parameter of type 'System.Collections.Generic.IEnumerator1[System.String]' of method 'Void Enum(System.Collections.Generic.IEnumerator
1[System.String])'
请帮忙。
您似乎很困惑 - 查看 C# 编译器如何生成类似的表达式树可能会有所帮助。无论如何,你犯了一些错误:
IEnumerable<T>
不是 IEnumerator<T>
。它们不可互换。
param2
是一个采用 SampleExpression
的参数表达式,而您的 lambda 实际上需要 IEnumerator<string>
.
ep
是常量表达式的常量表达式。那不是你想要的。删除外部 Expression.Constant
.
- 实际上并没有使用 lambda 参数 - 您可以只使用
Func<string>
而不是 Func<IEnumerator<string>, string>
。
- 您的表达式树没有 return 值,而 lambda 期望 return 一个
string
.
假设你想要一个接受 IEnumerator<string>
的 lambda 并用它来调用 SampleExpression.SampleEnum
,你可以使用这样的东西:
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!";
}
}
这是我的 class:
class SampleExpression
{
public static void SampleEnum(IEnumerator<string> ien)
{
while (ien.MoveNext())
{
Console.WriteLine(ien.Current);
}
}
}
这就是我尝试调用 SampleEnum
方法的方式:
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());
}
我在尝试创建方法调用表达式的行中收到以下错误:
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])'
请帮忙。
您似乎很困惑 - 查看 C# 编译器如何生成类似的表达式树可能会有所帮助。无论如何,你犯了一些错误:
IEnumerable<T>
不是IEnumerator<T>
。它们不可互换。param2
是一个采用SampleExpression
的参数表达式,而您的 lambda 实际上需要IEnumerator<string>
.ep
是常量表达式的常量表达式。那不是你想要的。删除外部Expression.Constant
.- 实际上并没有使用 lambda 参数 - 您可以只使用
Func<string>
而不是Func<IEnumerator<string>, string>
。 - 您的表达式树没有 return 值,而 lambda 期望 return 一个
string
.
假设你想要一个接受 IEnumerator<string>
的 lambda 并用它来调用 SampleExpression.SampleEnum
,你可以使用这样的东西:
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!";
}
}