gpt4 book ai didi

c# - 使用自定义方法构造 AndAlso/OrElse LINQ 表达式

转载 作者:行者123 更新时间:2023-11-30 21:41:23 24 4
gpt4 key购买 nike

我正在尝试传递自定义 MethodInfoExpression.AndAlsoOrElse工厂方法(分别用于 &&|| 运算符)。这些运营商使用短路,这使得这很困难,但通常是 &|使用运算符(以及 truefalse 运算符)。但是,Expression.AndAlso/OrElse 的 MSDN 文档没有提到 true 或 false 运算符。

为了测试,我声明了一个使用普通 & 的方法两个整数的运算符:

public static int And(int a, int b) {
return a & b;
}

注意返回类型必须是int而不是 bool以避免异常。
然后我构造表达式:

var expr = Expression.AndAlso(
Expression.Constant(0),
Expression.Constant(5),
new Func<int, int, int>(And).Method
);

这会导致异常:

The user-defined operator method 'And' for operator 'AndAlso' must have associated boolean True and False operators.

奇怪的是,如果我使用具有 true 的自定义结构,也会抛出错误和 false运营商。如果结构重载 &,我可以避免它运算符和我传递了那个重载,但如果我传递了不同的方法则不会。不过,其他非短路运算符使用自定义方法。

问题是我不知道如何为 true 传递方法和 false运算符。我首先想到我可以将它们组合为委托(delegate),但不同的方法具有不兼容的签名。有没有办法把这些方法传入?


大局观

我正在构建一个用于解释表达式以支持提前编译的系统。它支持对 AndAlso/OrElse 运算符使用自定义方法,目前采用自定义方法 Func<InterpretedExpression, InterpretedExpression, object> (当表达式被解释而不是编译时起作用)。如果它导致问题(这是由于它没有可访问的 truefalse 方法),可以很容易地更改它。


注意:我正在使用 Visual Studio 的 C# Interactive 窗口进行测试,但最终需要支持 .NET 3.5(尽管有关较新版本的信息仍然有用且值得赞赏)。

最佳答案

The problem is that I don't know how to pass methods for the true and false operators in. I first thought I could maybe combine them as delegates, but the different methods have incompatible signatures. Is there any way to pass these methods in?

简短的回答是否定的,你不能。

查看 reference source implementation (不幸的是,它确实应该在文档中),看起来传递的方法具有以下约束:

(1) 应该是一个static non generic 有签名的方法

static T Method(T arg0, T arg1);

其中 T 不能是开放通用类型

(2) 方法的声明类型必须定义运算符truefalse

由于运算符 truefalse 要求参数类型与声明类型相同,因此结合 (1) 确实限制了对类/结构的使用 T 声明静态方法和 truefalse 运算符。

换句话说,一种具有按位 &/| 运算符语义的方法,实际上不会重载这些运算符。

所以它只能用于这样的类型:

public struct IntWrapper
{
public readonly int Value;
public IntWrapper(int value) { Value = value; }
public static IntWrapper And(IntWrapper a, IntWrapper b) { return new IntWrapper(a.Value & b.Value); }
public static bool operator true(IntWrapper x) { return x.Value != 0; }
public static bool operator false(IntWrapper x) { return x.Value == 0; }
}

用法:

var expr = Expression.AndAlso(
Expression.Constant(new IntWrapper(0)),
Expression.Constant(new IntWrapper(5)),
new Func<IntWrapper, IntWrapper, IntWrapper>(IntWrapper.And).Method
);

我想这限制了您所追求的更普遍的用法。

关于c# - 使用自定义方法构造 AndAlso/OrElse LINQ 表达式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43434080/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com