Nicholas-Chen

导航

C#回忆录五(对象的等值性与为一性)

我们经常要去判断两个对象是否相等,在不同的情况下,相等的意义不一样。比如,int i=0; int j=0;我们会说他们相等,意思是值相等。再来考虑下面几行代码。
1 class RefObject
2 {
3     public int value;
4 }
5 
6 RefObject ro1 = new RefObject();
7 RefObject ro2 = new RefObject();
8 RefObject ro3 = ro1;
ro1和ro2虽然内部的值相等,value均为默认初始值0,但他们不是同一个对象,他们处于托管堆中不同的地址。ro3和ro1是同一个对象,指向托管堆中同一块内存。
System.Object提供了一个虚拟的方法Equals,用来判断两个对象是否相等。由于所有的类型都继承自System.Object,这就确保我们可以对所有的对象进行判等的操作。我们可以实现自己的Equals方法。但是它必须满足一定的条件。
第一:自反性。x.Equals(x)必须为true。
第二:可逆。x.Equals(y) =>y.Equals(x)。
第三:传递。x.Equals(y) AND y.Equals(z) => x.Equals(z)。
第四:前后一致。 一开始x.Equals(y) = true,如果两个对象的值没有发生变化,以后x.Equals(y) = true。
在重写Equals方法时,分为两种情况考虑。
第一:他的基类没有重写Object的方法。下面的代码展示怎样为它实现Equals方法。
 1 public SubType
 2 {
 3     RefType m_refType;//一个引用类型
 4     ValueType m_valueType;//一个值类型
 5     public override bool Equals(Object obj)
 6     {
 7         if(obj == null){return false;}//因为this不为null,所以如果obj为null两个对象不可能相等
 8         if(this.GetType()!=obj.GetType()){return false;}//类型不同不可能相等
 9         SubType other = (SubType)obj;//类型在这里一定相等
          
if(!Object.Equals(m_refType,other.m_refType )){return false;}//比较其中的引用类型字段  
10         if(!m_valueType.Equals(other .m_valueType)){return false;}//比较其中的值类型字段 
11         return true//到这里最终相等
12      }
13 }
一般对于引用类型,我们调用Object.Equals这个静态方法,这样即使出现其中之一为null的情况也能正确处理。而对于值类型,则不应该调用他,一方面,值类型不可能为null,另一方面调用他会导致装箱.


posted on 2006-12-14 22:49  nicholas_chen  阅读(216)  评论(0)    收藏  举报