==、Equals()、ReferenceEquals()之间的异同

来源:互联网 发布:语音互动软件 编辑:程序博客网 时间:2024/04/30 08:36
 

我们都知道字符串之间的比较,一般使用的是Equals()方法,当然也有不少人使用“==”运算符,但这两者之间有根本性区别,下面我们来看一下。

通常比较对象使用三种方式,第一是使用“==”运算符,第二是使用“Equals()”方法,第三是使用“RefereceEquals()”方法。

先来看使用“==”进行比较的情况。“==”针对的是值类型的比较,或者说是针对的是栈的比较。栈内存放的主要有两种类型,对值类型而言,存放的就是该变量的值,对引用类型而言,栈内存放的是该变量的地址。与此相应,当用“==”比较两个值类型的时候,比较的就是它们真正的值,而比较两个引用类型的变量时,比较的只是他们的地址,而不是值,因此两个引用类型如果拥有相同的值,但用“==”比较,结果不一定为true,因为一旦两者的地址不同,则一定返回false,不管它们的值是否相等。可以参照一下的例子:

string str1 = new string();

string str2 = new string();

str1 = “xyz”;

str2 = “xyz”;

如果用Equals()比较返回true,用“==”比较则返回false

 

string str1 = new string();

str1 = “xyz”;

string str2 = “xyz”;

如果用Equals()比较返回true,用“==”比较,同样返回true,这主要是因为“xyz”已经存放在字符串池中了,当给str2赋值的时候,str2实现并没有new,即没有新开辟内存,所以它首先会在字符串池中寻找是否有“xyz”这个值,如果有的话,直接指向它的地址,所以str2str1是具有相同地址的。

 

再来看看“Equals()”的情况。根据上面的分析,比较字符串的时候,一般是采用“Equals()”方法,因为Equals()方法比较的是两个字符串的值,而非字符串的地址。但是,必须注意的是,Equals()方法的本意绝非如此!Equals()方法的本意就是用来对引用类型进行比较的,也就是比较它们的地址,而非值。而string类的Equals()方法明显是被.Net重写的,所以就变成了比较值而非引用。事实上,Equals()方法经常会被重写,以比较值。例如,如果Hashtable的键值为对象的时候,就需要重写这个对象的Equals()方法,变成比较值,否则字典容易报错。Equals()方法有虚方法和静态方法两种,都是用来比较引用的,我们重写的是其虚方法。

另外注意,如果对值类型使用Equals()方法,则结果一定为false,因为该值类型的变量首先会进行装箱成引用类型,从而指向不同的地址,所以结果一定为false。但在C#3.0版本中,如果两个相等的int型数值比较,结果为true,这表明值类型的Equals()方法也被重写过。

 

最后看一下ReferenceEquals()方法。从名字就能看出来,它是用来比较引用的,与Equals()类似,但无法被重写。

原创粉丝点击