对象等同性的分析与实现 - C#

当我们创建自己的类型时(无论是class还是struct),都应为类型定义“等同性”的含义。

C#提供了4种不同的函数来判断两个对象是否“相等”。

public static bool ReferenceEquals(object left, object right);
public static bool Equals(object left, object right);
public virtual bool Equals(object obj);
public static bool operator == (MyClass left, MyClass right);

当然,这4个方法并不是等同性比较的唯一选择。覆写Equals()方法的类型也应该实现 IEquatable<T>。实现值语义(value semantics)的类型同时还应该实现IStructralEquatable 接口。这就意味着一共有6种方法来表达等同性。

C#允许我们创建两种类型:值类型和引用类型。如果两个引用类型的变量指向的是同一个对象,它们将被认为是“引用相等”。如果两个值类型的变量类型相同,而且包含同样的内容,它们被认为是“值相等”。这也正是等同性判断需要如此多方法的原因。
虽然看起来做等同性判断有些过于复杂,但是不要担心,我们可以简化这个问题。

不应该覆写的方法

对于前两个静态函数,我们永远都不应该去重新定义。

1. Object.ReferenceEquals()

如果两个变量指向同一个对象,也就是它们拥有同样的对象标识,那么Object.ReferenceEquals() 方法将返回true。无论比较的是引用类型还是值类型,该方法判断的依据都是对象标识,而不是对象内容。这也意味着,如果我们使用ReferenceEquals() 来比较两个值类型,其结果将永远返回false,即使我们将一个值类型和它自身进行比较,ReferenceEquals() 的返回值仍是false,其原因在于装箱。

我们永远都不应该去重新定义Object.ReferenceEquals() 方法,因为它已经完美地完成了所需要完成的工作——判断两个不同变量的对象标识是否相等。

2. Object.Equals()

当你不知道两个变量的运行时类型时,可以使用该方法来判断两个变量是否相等。任何时候我们比较两个变量都是System.Object 的实例,值类型变量和引用类型变量都是如此。那么该方法又将如何判断两个变量是否相等呢?因为该方法并不知道它们的类型,而等同性判断又是依赖类型的。答案很简单,该方法会将判断的具体操作委托给其中一个类型来做。

public static bool Equals(object left, object right)
{
   
	// check object identity
	if (Object.ReferenceEquals(left, right))
		return true;

	// both null reference handled above
	if (Object.ReferenceEquals(left, null) ||
	  Object.RefernceEquals(right, null))
		return false;
	return left.Equals(right);
}

从上面的代码可以看出,在静态 Equals() 方法的内部,实际上是通过调用left参数的实例Equals() 方法来判断两个对象是否相等的。

ReferenceEquals() 方法一样,你永远不要去重新定义或覆写静态的 Object.Equals() 方法,因为它也已经很好地完成了其应该做的动作,即在不知道对象的运行时类型时,判断二者是否相等。

可以覆写的方法

下面我们讨论那些可以被覆写的方法,但是在此之前,我们先来简要谈谈等同性关系在数学上的定义。对于等同性判断,需要保证我们给出的定义是满足等同性在数学方面的几个

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值