为什么在.net中存在Equals的静态和非静态重载

本文关键字:静态 重载 Equals net 存在 为什么 | 更新日期: 2023-09-27 17:58:59

为什么.NET的对象类中有两个Equals重载?如果我想有一个自定义的相等函数,例如,这样我就可以使用集合或字典,我应该重写这两个函数(除了GetHashCode),还是只重写其中一个就足够了。

为什么在.net中存在Equals的静态和非静态重载

您不能覆盖静态版本。

之所以使用静态版本,是因为您可以调用object.Equals(myObject, myOtherObject),而无需事先检查null。

在内部,它只检查null(如果两个对象都为null,则返回true),然后委托给myObject.Equals(myOtherObject)。因此,您只需要重写非静态的Equals方法。

您不能重写静态方法。

只覆盖非静态方法就可以了。。。

阅读本文:如何:覆盖静态方法:

为什么我们不能覆盖静态成员

真的吗,为什么?如果你仔细想想,这只是常识。覆盖普通(实例)成员使用虚拟调度将合同与执行分开的机制。这个协定在编译时是已知的(实例成员签名),但是只有在运行时才知道实现(对象的具体类型提供了具体的实现)。你不知道具体的类型编译时实现的。

理解这一点很重要:当类型从其他类型,它们履行一个共同的契约,而静态类型是不受任何合同约束(从纯粹OOP的角度来看)。有语言中没有技术方法将两个静态类型与"继承"合同。如果要"覆盖"中的Log方法两个不同的地方,我们如何知道我们在这里打电话给哪一个:Log.Message("实现是什么?")

对于静态成员,可以通过显式指定类型来调用它们在其上定义它们。也就是说,你直接打电话给执行,这同样不受任何合同的约束。

顺便说一句,这就是静态成员不能实现接口的原因。和这就是为什么虚拟调度在这里毫无用处——所有客户端都直接调用实现,无需任何合约。

如果"第一个"对象为null,则存在静态方法。例如,如果a为null,而b不为null,则不能运行a.Equals(b),但可以运行object.Equals(a, b)

您应该(并且可以)只重写实例方法,原因有两个。首先,不能重写静态方法。其次,静态方法最终将调用非静态方法。

有关更多信息,请参阅文档。