【问题标题】:Why Expression.Call is throwing parameters error为什么 Expression.Call 抛出参数错误
【发布时间】:2019-04-11 14:21:45
【问题描述】:

我正在尝试提取 Count 方法,以便以后可以重用它来构建表达式树。

var g = Expression.Parameter(typeof(IEnumerable<float?>), "g");
var countMethod = typeof(Enumerable)
    .GetMethods()
    .Single(m => m.Name == "Count" && m.GetParameters().Count() == 1);
var countMaterialized = countMethod
    .MakeGenericMethod(new[] { g.Type });
var expr = Expression.Call(countMaterialized, g);

它会抛出这个错误:

System.ArgumentException: 'System.Collections.Generic.IEnumerable1[System.Nullable1[System.Single]] 类型的表达式不能用于'System.Collections.Generic.IEnumerable1[System.Collections.Generic.IEnumerable1[ System.Nullable1[System.Single]]]' of method 'Int32 Count[IEnumerable1](System.Collections.Generic.IEnumerable1[System.Collections.Generic.IEnumerable1[System.Nullable1[System.Single]]])''

我错过了什么?

【问题讨论】:

  • 泛型的类型参数应该是float?,而不是IEnumerable&lt;float?&gt;。猜猜哪个g.Type回来了?
  • 如果您查看Enumerable.Count&lt;TSource&gt; 的声明,您会发现TSource 不是IEnumerable&lt;T&gt;,而只是IEnumerable 中的项目类型,因此将MakeGenericMethod 更改为使用@ 987654334@ 而不是 g.Type
  • 在将 typeof(float?) 放入 MakeGenericMethod 后它起作用了

标签: c# linq generics reflection expression


【解决方案1】:

您的参数类型是正确的,但您的泛型类型应该是“float”?而不是“IEnumerable”。

var g = Expression.Parameter(typeof(IEnumerable<float?>), "g");

// get the method definition using object as a placeholder parameter
var countMethodOfObject = ((Func<IEnumerable<object>, int>)Enumerable.Count<object>).Method;

// get the generic method definition
var countMethod = countMethodOfObject.GetGenericMethodDefinition();

// create generic method
var countMaterialized = countMethod.MakeGenericMethod(new[] { typeof(float?) });

// creare expression
var countExpression = Expression.Call(countMaterialized, g);

var expression = Expression.Lambda<Func<IEnumerable<float?>, int>>(countExpression, g);

IEnumerable<float?> floats = Enumerable.Range(3, 5).Select(v => (float?)v);
var count = expression.Compile().Invoke(floats);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-19
    • 1970-01-01
    • 1970-01-01
    • 2023-03-29
    • 1970-01-01
    • 2022-08-19
    相关资源
    最近更新 更多