为什么我的具有多个参数的 LINQ 表达式无法编译?
Why is my LINQ Expression with multiple parameters not compiling?
我想扩展 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<> 限制为 4 个参数。
:edit2
建议的 Compile().Invoke()
解决方法在所有与查询相关的情况下都不起作用(我需要)。因此,我从 LINQKit 项目创建了一个分支,并添加了一些代码以支持最多 16 个参数:
https://github.com/ViRuSTriNiTy/LINQKit/commit/bcca71978ef3fbb988d242463adfbc4e9cd42565
LinqKit 1.1.2 I've found on nuget (and on 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);
}
您可以直接调用 .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);
}
}
当您添加第五个参数时,您将绑定到与 LinqKit
中的参数不同的 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 ().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);
}
}
我想扩展 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<> 限制为 4 个参数。
:edit2
建议的 Compile().Invoke()
解决方法在所有与查询相关的情况下都不起作用(我需要)。因此,我从 LINQKit 项目创建了一个分支,并添加了一些代码以支持最多 16 个参数:
https://github.com/ViRuSTriNiTy/LINQKit/commit/bcca71978ef3fbb988d242463adfbc4e9cd42565
LinqKit 1.1.2 I've found on nuget (and on 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);
}
您可以直接调用 .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);
}
}
当您添加第五个参数时,您将绑定到与 LinqKit
中的参数不同的 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 ().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);
}
}