参考:http://www.cnblogs.com/pursue/articles/1614285.html
有时必须比较两个值是否相等。 在某些情况下,您测试的是“值相等性”(也称为“等效性”),意即两个变量包含的值相等。 而在其他情况下,则必须确定两个变量是否引用内存中的同一基础对象。 这种类型的相等性称为“引用相等性”(或“标识”)。
1.Object.ReferenceEquals(object objA,object objB)
作用:比较两个引用类型的对象是否是对同一对象的引用,即引用相等性。
(1)先检查objA、objB是否为null,如果仅有一个为null,返回false,如果两个均为null,返回true
(2)如果 objA、objB为值类型,则先进行装箱到不同的对象实例,因此对于两个值类型,无论它们的值是否相等,总返回false;
(3)如果 objA、objB均为字符串,比较的也是字符串的引用,与值无关。但由于c#字符串池的机制使得字符串的比较有些特殊,见下面的补充部分。
补充:
对多个引用赋值同一个字符串对象,CLR的解决方法更加巧妙。在默认情况下CLR会使用字符串池的机制,CLR启动的时候,在内部创建一个容器,它以键值对的形式存在,键值是字符串对象内容,值是字符串在托管堆上的引用,当一个新的字符串对象创建的时候CLR检查在这些值中是否已经存在这个字符串对象,如果已经存在就返回对应的值,也就是在托管堆中的引用,如果不存在就在这个容器中中开辟空间存放这个字符串,返回在他的引用。
这里还是用一段代码来说明:
public void StringPoolTest()
{
string str1 = "789";
string str2 = "789";
Console.WriteLine(Object.ReferenceEquals(str1 , str2));
string str3 = "7" + "8" + "9";
Console.WriteLine(Object.ReferenceEquals(str1, str3));
char[] chars = new char[] { '7', '8', '9' };
string str4 = new string(chars);
Console.WriteLine(object.ReferenceEquals(str1 , str4));
}
输出结果:
前两次都输出true说明str1和str2都指向同一个堆引用,最后一个输出false是因为它使用new关键字进行内存分配,字符串池机制不起作用。
这里注意string str3 = "7" + "8" + "9";这个语句在正常的情况下只分配了一次内存,这个也是CLR的优化,在这里就没有分配内存了,因为str1这里已经分配好了。
2.object.Equals(object objA,object objB)