使用 Reflector 或 DotPeek,相等运算符重载的 System.Linq.Data.Binary 实现如下所示:
[Serializable, DataContract]
public sealed class Binary : IEquatable<Binary>
{
...
public static bool operator ==(Binary binary1, Binary binary2)
{
return ((binary1 == binary2) || (((binary1 == null) && (binary2 == null)) || (((binary1 != null) && (binary2 != null)) && binary1.EqualsTo(binary2))));
}
我一定错过了一些明显的东西,或者存在一种我不知道的机制(例如在体内隐式调用 object == ?)。我承认,我很少需要重载标准运算符。
为什么这个实现不会导致无限递归(一个简单的测试表明它不会无限递归)?第一个条件表达式是binary1==binary2,在运算符重载的实现中,如果您在实现之外使用binary1==binary2,就会调用该运算符重载,而且我也想在实现内部使用。
我预计这是你的反编译器中的一个错误。 Redgate Reflector 有同样的错误,我已经在 ILSpy 中找到它 https://github.com/icsharpcode/ILSpy/issues/217 too.
之所以很难反编译,是因为它巧妙地测试了 C# 的重载规则。原始代码很可能是这样的(object)obj1==(object)obj2
,但这种转换在 IL 本身中是看不到的。就运行时而言,将任何引用类型强制转换为基类型都是无操作的。然而,它确实让 C# 选择引用相等操作码,而不是调用重载的相等运算符。
IMO 在反编译器中实现这一点的正确方法是始终将引用相等性检查反编译为(object)obj1==(object)obj2
然后优化冗余转换(如果它们不影响重载解析)。这种方法也将解决方法重载的类似问题。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)