为什么我的LINQ表达式有多个参数没有编译?

时间:2015-06-19 12:41:31

标签: c# linq parameters expression

我想扩展LINQ表达式(DoSomething)

using LinqKit; // for System.Linq.Expressions.Expression<>.Invoke()

public class Expressions
{
  public static System.Linq.Expressions.Expression<
    System.Func<int, int, int, int, bool>>
      DoSomething =
        (a, b, c, d) => false;
}

public class ExpressionTester
{
  public ExpressionTester()
  {
    Expressions.DoSomething.Invoke(1, 2, 3, 4);
  }
}

带有附加参数但不编译:

public class Expressions
{
  public static System.Linq.Expressions.Expression<
    System.Func<int, int, int, int, int, bool>>
      DoSomething =
        (a, b, c, d, e) => false;
}

public class ExpressionTester
{
  public ExpressionTester()
  {
    Expressions.DoSomething.Invoke(1, 2, 3, 4, 5);
  }
}

The best overloaded method match for 'System.Linq.Expressions.Expression.Invoke(System.Linq.Expressions.Expression, params System.Linq.Expressions.Expression[])' has some invalid arguments
error CS1503: Argument 1: cannot convert from 'int' to 'System.Linq.Expressions.Expression'
error CS1503: Argument 2: cannot convert from 'int' to 'System.Linq.Expressions.Expression'
error CS1503: Argument 3: cannot convert from 'int' to 'System.Linq.Expressions.Expression'
error CS1503: Argument 4: cannot convert from 'int' to 'System.Linq.Expressions.Expression'
error CS1503: Argument 5: cannot convert from 'int' to 'System.Linq.Expressions.Expression'

参数数量是否有未记录的限制?

:编辑

感谢未知作者在10秒后删除答案的答案,我发现LinqKit是用.NET 3.5编译的,但这导致了System.Func&lt;&gt;的限制。到4个参数。

:EDIT2

建议的Compile().Invoke()解决方法在所有与查询相关的情况下都不起作用(我需要)。因此,我从LINQKit项目创建了一个fork,并添加了一些代码以支持最多16个参数:

https://github.com/ViRuSTriNiTy/LINQKit/commit/bcca71978ef3fbb988d242463adfbc4e9cd42565

3 个答案:

答案 0 :(得分:4)

当您添加第五个参数时,您将绑定到与public static void main(String[] args) { BigInteger a = BigInteger.valueOf(7); for (int i = 2; i < 100; i++) { a = BigInteger.valueOf(3).modPow(a, BigInteger.valueOf(10).pow(i)); System.out.println(a); } } 中的Invoke不同的LinqKit

public static TResult Invoke<T1, T2, T3, T4, TResult> (
    this Expression<Func<T1, T2, T3, T4, TResult>> expr, T1 arg1, T2 arg2, T3 arg3, T4 arg4)
{
    return expr.Compile ().Invoke (arg1, arg2, arg3, arg4);
}

请注意,没有一个包含5个参数,因此您最终绑定到Expression.Invoke,其参数数组为Expression s:

public static InvocationExpression Invoke(Expression expression, params Expression[] arguments) {
    return Invoke(expression, (IEnumerable<Expression>)arguments);
}

幸运的是,您只需在表达式上调用Compile()将其转换为委托即可从LinqKit复制实现:

public class ExpressionTester
{
  public ExpressionTester()
  {
    Expressions.DoSomething.Compile().Invoke(1, 2, 3, 4, 5);
  }
}

答案 1 :(得分:3)

我在nuget上找到的LinqKit 1.1.2(以及github)最多支持Invoke的四个参数......

public static TResult Invoke<T1, T2, T3, T4, TResult>(this Expression<Func<T1, T2, T3, T4, TResult>> expr, T1 arg1, T2 arg2, T3 arg3, T4 arg4)
{
    return expr.Compile()(arg1, arg2, arg3, arg4);
}

基于4个参数,可以轻松完成5个参数。

public static TResult Invoke<T1, T2, T3, T4, T5, TResult>(this Expression<Func<T1, T2, T3, T4, T5, TResult>> expr, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5)
{
    return expr.Compile()(arg1, arg2, arg3, arg4, arg5);
}

答案 2 :(得分:2)

您只需拨打.Compile().Invoke()即可。此代码编译:

public class Expressions
{
    public static System.Linq.Expressions.Expression<
      System.Func<int, int, int, int, int, bool>>
        DoSomething =
          (a, b, c, d, e) => false;
}

public class ExpressionTester
{
    public ExpressionTester()
    {
        Expressions.DoSomething.Compile().Invoke(1, 2, 3, 4, 5);
    }
}