这个类的方法
到目前为止,一切都很好。但是,
为什么会这样呢?为什么三种提出的方法都没有调用
编辑:我用于测试的类如下:
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);
}
}
把代码编译成这个IL代码:
.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);
operator==
或Equals
方法没有被o is null
、o == null
或Equals(o, null)
中的任何一个调用。 - Thomas Flinkowpublic static bool Equals(Object objA, Object objB)
的源代码,它应该会调用。https://referencesource.microsoft.com/#mscorlib/system/object.cs,f2a579c50b414717,references - Rand RandomMyClass
没有显式继承任何类,但它通过设计继承了Object
,因此我可以重写运算符和Equals
方法。 - Thomas Flinkow