C# 在相等运算符实现中引用相等运算符
使用Reflector或DotPeek,相等运算符重载的System.Linq.Data.Binary实现如下所示:C# 在相等运算符实现中引用相等运算符,c#,.net,C#,.net,使用Reflector或DotPeek,相等运算符重载的System.Linq.Data.Binary实现如下所示: [Serializable, DataContract] public sealed class Binary : IEquatable<Binary> { ... public static bool operator ==(Binary binary1, Binary binary2) { return ((binary1 == b
[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))));
}
[可序列化,数据契约]
公共密封类二进制:IEquatable
{
...
公共静态布尔运算符==(二进制二进制二进制1,二进制二进制二进制2)
{
返回((binary1==binary2)| |((binary1==null)和&(binary2==null))| |((binary1!=null)和&(binary2!=null))和&binary1.EqualsTo(binary2));
}
我肯定错过了一些明显的东西,或者有一种我不知道的机制正在发生(比如在体内隐式调用object==吗?)
为什么这个实现不会导致无限递归(一个简单的测试表明它不会无限递归)?第一个条件表达式是binary1==binary2,在运算符重载的实现内,如果在实现外使用binary1==binary2,就会调用该表达式,我也会认为在实现内也是如此。这显然是ReSharper(和dotpeek)版本中的一个bug。版本6.0(6.0.2202.688)ReSharper的操作是否正确:
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);
}
我想这可能是你的反编译器中的一个bug。Redgate Reflector也有相同的bug,我也有 这很难反编译的原因是,它巧妙地测试了C#重载规则。原始代码很可能类似于
(object)obj1==(object)obj2
,但在IL本身中看不到这种转换。就运行时而言,将任何引用类型强制转换为基类型是不可行的。但是,它确实让C#选择引用相等操作码,而不是调用重载相等运算符
在反编译器中实现这一点的正确方法是始终将引用相等检查反编译为
(object)obj1==(object)obj2
然后优化掉冗余强制转换,如果它们不影响重载解析。这种方法也可以解决方法重载的类似问题。对不起,我的帖子中是说Reflector,而不是Resharper(我已更正)。有趣的是,当前的Resharper做得对,但DotPeek(由同一家公司提供)没有。