【发布时间】:2018-03-28 07:46:55
【问题描述】:
这个类的方法
public class NullTester
{
public bool EqualsNull<T>(T o) where T : class
{
return o == null;
}
public bool IsNull<T>(T o) where T : class
{
return o is null;
}
public bool EqualsCall<T>(T o) where T : class
{
return object.Equals(o, null);
}
}
.method public hidebysig
instance bool EqualsNull<class T> (
!!T o
) cil managed
{
.maxstack 8
IL_0000: ldarg.1
IL_0001: box !!T
IL_0006: ldnull
IL_0007: ceq // IMPORTANT
IL_0009: ret
} // end of method C::EqualsNull
.method public hidebysig
instance bool IsNull<class T> (
!!T o
) cil managed
{
.maxstack 8
IL_0000: ldarg.1
IL_0001: box !!T
IL_0006: ldnull
IL_0007: ceq // IMPORTANT
IL_0009: ret
} // end of method C::IsNull
.method public hidebysig
instance bool EqualsCall<class T> (
!!T o
) cil managed
{
.maxstack 8
IL_0000: ldarg.1
IL_0001: box !!T
IL_0006: ldnull
IL_0007: call bool [mscorlib]System.Object::Equals(object, object) // IMPORTANT
IL_000c: ret
} // end of method C::EqualsCall
到目前为止,一切都很好。
但ceq 和System.Object::Equals(object, object) 都不会考虑可能被覆盖的op_Equality 或Object.Equals。
这是为什么呢?为什么三种提议的方法都没有调用operator== 或覆盖的Equals 方法? System.Object::Equals(object, object) 不应该自动调用任何被覆盖的Equals 方法吗?
编辑: 我用于测试目的的类如下所示:
public class MyClass
{
public static bool operator ==(MyClass m1, MyClass m2) => throw new Exception();
public static bool operator !=(MyClass m1, MyClass m2) => throw new Exception();
public override bool Equals(object obj) => throw new Exception();
}
以下三个方法都没有调用MyClass 的任何覆盖成员:
NullTester tester = new NullTester();
MyClass myClass = new MyClass();
tester.IsNull(myClass);
tester.EqualsNull(myClass);
tester.EqualsCall(myClass);
【问题讨论】:
-
在我看来,尝试将对象的结果与 == 运算符进行比较更改为 null 似乎是糟糕的设计。其他将使用您的代码的程序员可能会感到困惑。
-
@Neijwiert 你是对的,但我不想改变任何东西,我只想知道为什么@987654339 中的任何一个都没有调用覆盖的
operator==或Equals方法@、o == null或Equals(o, null)。 -
为什么你认为 object.Equals(a, b) 不会调用 a 的覆盖方法? - 查看
public static bool Equals(Object objA, Object objB)的源代码应该是referencesource.microsoft.com/#mscorlib/system/… -
@RandRandom 这可能是我的代码有问题,但
Equals方法中没有调试器断点被命中。另外,我将Equals方法更改为public override bool Equals(MyClass o, MyClass o2) => throw new Exception();,它也没有被调用。 -
你能显示你的代码吗,如果可能的话,mcve 会很好。 stackoverflow.com/help/mcve
标签: c# operator-overloading cil