无法传递IEnumerable<;字符串>;作为Expression.Call中的参数

本文关键字:Expression 作为 Call 参数 gt 字符串 IEnumerable lt | 更新日期: 2023-09-27 18:29:44

这是我的类:

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());
    }

我在试图创建方法调用表达式的行中得到以下错误:

"System.Linq.Expressions.TypedConstantExpression"类型的表达式不能用于"System.Collections.Generic.IEnumerator 1[System.String]' of method 'Void Enum(System.Collections.Generic.IEnumerator 1[System.String])"类型的参数

请帮忙。

无法传递IEnumerable<;字符串>;作为Expression.Call中的参数

您似乎很困惑——看看C#编译器如何生成类似的表达式树可能会有所帮助。无论如何,你都会犯一些错误:

  • IEnumerable<T>不是IEnumerator<T>。它们不能互换
  • param2是一个采用SampleExpression的参数表达式,而lambda实际上需要IEnumerator<string>
  • ep是常数表达式的常数表达式。这不是你想要的。拆下外部Expression.Constant
  • lambda参数实际上并没有被使用——您可以只使用Func<string>而不是Func<IEnumerator<string>, string>
  • 表达式树没有返回值,而lambda期望返回string

假设您想要一个接受IEnumerator<string>并使用它来调用SampleExpression.SampleEnum的lambda,那么您可以使用以下内容:

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!";
    }
}