.NET框架是用于建立Inte.net时代应用程序的综合性平台,它允许开发人员建立使用Windows平台的完全富于新特色的应用程序。在VS2008中,已经完全支持.net架构。在此笔者就以VS平台为基础, 谈谈对象的比较与复制等要点。
一、Equals()与==的差异性。
Equals与==都可以用来比较对象。他们的结果是否相同呢?可以这么说,他们两个有本质的不同。作为程序开发人员必须深入的了解他们之间的差异,以便在后续编写代码的时候防止张冠李戴。
简单的说,Equals测试两个对象的等价性,而C#中的==用语测试引用是否相同。这是什么意思呢?假设笔者现在建立了如下两个对象。
Dim sale1 as new person(“luobo”)
Dim sale2 as new person(“luobo”)
这两条语句在VS平台中建立了两个对象,并且对其进行了初始化。这两个对象虽然对象名字不同,但是都有相同的内容。此时如果分别用以上两种方法会有什么不同的结果呢?当使用==符号来比较两个对象的时候,其比较的是两个对象的引用,或者更确切的说,比较的是两个对象的物理存储地址。很显然这两个对象虽然有相同的内容,但是其存储的地址是不同的。为此最后得出的结果是False。相反,当使用equals方法比较两个对象的时候, VS系统比较的是两个对象的内容,而不是存储其内容的地址。由于上面两个对象具有相同的内容,为此得到的结果是true。
那么什么时候该用什么样的方法呢?对于这个问题笔者做了一下总结。大家如果需要的话,可以参考如下的一些建议。
一是对于引用类型,可以使用==或者ls方法来测试引用的等价性。二是对于值类型,一般不能够使用==或者ls方法来进行判断。因为在定义中,值类型不能够通过引用来访问,故对他们进行比较在现实中是没有实际意义的。三是值类型一般是使用派生出来的equals方法,测试内容是否相同,它们不能够被覆盖。笔者最强调一下,一般不能够覆盖用于引用类型的equlas方法。通常情况下可以对用户类定义比较规则。如果不能够覆盖它,则默认的equals方法将会检查引用的等价性。
另外需要注意的是在.net架构中还有一个比较有用的方法:referenceequals方法。其主要用来测试两个引用是否指向同一个对象。如现在有两个对象,很有可能起对应的是同一个地址。这就好象一个人有两个名字一样。对对象的内容更改时,这两个引用所对应的内容也会随之更改(因为他们实际上对应的是同一个对象)。如在删除某个对象的时候,可能需要用到这个方法。
二、对象的浅拷贝与深拷贝。
在谈到对象的比较时笔者提到过,有时候可能两个引用指向同一个对象。如Sale1与Sale2都指向同一个对象Person。举例来说,现在有一个文件。用户在桌面上创建了这个文件的快捷方式。此时看起来有两个文件,但是实际上这个两个文件名字指向的都是同一个文件。要实现这个功能的话,就需要用到MemberwiseClone方法。简单的说,这个方法就是用于产生对象的浅拷贝。
浅拷贝一般只着眼与对象的表层。如果某个对象包含到其他对象的引用,则这个引用就会被这个方法所拷贝。也就是说,不仅对象可以被拷贝,其对象的引用也是可以被复制的。不过在使用这个方法的时候,需要注意,其是受到保护的。通常情况下,只有派生出来的类才能够调用这个方法。如开发人员通过如下方式来调用这个方法是不允许的。
Dim obj as new object1{}
Obj.memberwiseclone()
这主要是因为只有派生出来的类才能够调用这个方法。另外需要注意的是,这种方法一般只适用引用的拷贝,而不适合对象的拷贝。有浅拷贝那么就有深拷贝。如果要单独的拷贝一个对象,以及对象所引用的所有内容时(相当于是建立一个不同的对象,只是内容相同而已),就需要用到深拷贝。这主要是通过lconeable接口来实现的。采用深拷贝时,那么引用和指向的对象本身将都会被一起拷贝,或者说被拷贝的对象有了一个独立的副本。
显然深拷贝与浅拷贝都是涉及到对象的拷贝,但是实际的结果却相差深远。如果做一个形象的比较,浅拷贝就好象为某个文件建立一个“快捷方式”,而深拷贝就好象是“复制”了一个文件。表面上看起来一样,其实两者有本质的差异。作为开发人员,在应用程序设计与开发中,需要根据用户的需求选择合适的方法。如果需要的是两个独立的对象,那么就采用深拷贝。
三、等价的深入分析。
在VS平台中管理对象时,了解等价的含义非常重要。因为在很多的地方都需要进行对象的比较。而不同类型的对象对于等价这个概念的理解都有所不同。也就是说,等价的具体含义还是主要决定于所考虑的对象的类型。或者说,不同的对象类型对于“等价”可能有不同的定义,不能够一概而语。
如对于普通的值类型,等价的含义比较简单,就只表示他们只要有相同的内容,就表示等价。在实际开发过程中,对此要有清晰的认识。特别是将这个结果作为IF条件语句的条件时,更加要慎重。否则的话,很容易导致相反的结果。
如现在要开发一个应用程序,其大致的功能是:如需要在数据库中寻找条件符合年龄等于25岁、性别为男、户籍为浙江宁波的人的信息。此时可以建立一个对象,就涉及到对象的比较。根据这个需求,可以知道其主要比较的是内容。只要对象的内容相同即可。而不用管对象的地址。也就是说,这个需求中等价的含义是针对内容。如果不对此进行精确的定义,那么最后判断的结果就会相差很多。
笔者最后强调一次,等价的含义取决于所考虑的对象的类型。对象的类型不同,其等价的具体内涵是不同的。故当涉及到不同类型的对象比较时,该采取合适的方法。或者说,在比较对象之前,需要先对对象的类型进行强制的转换。