[英]Referencing equality operator within equality operator implementation
使用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有/同样的bug,我也在ILSpy中找到了它 。
这很难反编译的原因是因为它巧妙地测试了C#重载规则。 原始代码很可能类似于(object)obj1==(object)obj2
,但是这种转换在IL本身中是看不到的。 就运行时而言,将任何引用类型转换为基类型都是无操作。 但它确实让C#选择引用等式操作码而不是调用重载的相等操作符。
IMO在反编译器中实现它的正确方法是始终将引用相等性检查反编译为(object)obj1==(object)obj2
,然后在不影响重载(object)obj1==(object)obj2
优化冗余转换。 这种方法也将解决方法重载的类似问题。
这显然是你的ReSharper(和dotpeek)版本中的一个错误。 ReSharper版本6.0(6.0.2202.688)正确执行:
public static bool operator ==(Binary binary1, Binary binary2) {
if ((object)binary1 == (object)binary2)
return true;
if ((object)binary1 == null && (object)binary2 == null)
return true;
if ((object)binary1 == null || (object)binary2 == null)
return false;
return binary1.EqualsTo(binary2);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.