== Equals ReferenceEquals 三个相等性测试,是.NET提供给程序员使用的三个方法,他们之间有什么联系和区别,你真的仔细研究过?虽然以前也多多少少知道一点,可是有时候又不免混淆他们之间的概念和所适用的场合,决定作一个总结系统的描述这三个宝宝html
在编程中实际上咱们只须要这两种比较,c#中类型也就这两种程序员
(1)值类型的比较:通常咱们就是判断两个值类型实例的各自包含的值是否相等编程
(2)引用类型的比较:因为引用类型在内存中的分布有两部分,一个是引用类型的引用(存在于线程栈中),一个是引用类型的值(存在于托管堆);因此咱们比较引用类型也就存在两种比较c#
默认状况下:值类型比较的是两个值是否相等(不装箱状况下),引用类型比较的是两个引用是否相等。安全
定义:静态相等符号,对应存在的!=,这个符号是一个能够重载的二元操做符,能够用于比较两个对象是否相等。使用==比较对象时,C#在编译时就决定了所比较的类型,并且不会执行任何虚方法(Object.Equals)。这是你们所指望的相等行比较。ide
注意:可是某些内置的引用类型重载了==符号,例如string就重载==,使其比较的不是两个字符串的引用,而是比较的两个字符串字面量是否相等,以下图,因此对于引用类型最好不要使用==符号进行相等性比较,避免混淆。【对于引用类型利用==除了string是比较其值外,其他都是比较其引用,由于string是常常须要操做,因此会直接比较其值,因此会对其特殊对待,因此若是碰见特殊的引用类型须要查看一下是否进行了==重载,默认状况你们均可以把==在比较引用类型时当成比较引用!】测试
值类型的==比较:虽然i和j在栈上具备不一样的内存空间,可是他们的代数值都为5;m和n类型被自动转换并比较代数值spa
int i = 5; int j = 5; Console.WriteLine(i == j);//值类型比较代数值 输出True int m = 6; double n = 6.0; Console.WriteLine(m == n);//类型自动转换并比较数值 输出True
引用类型==比较:以下代码,两个object对象都在堆上申请了空间,在线程栈上存在两个不一样的引用,因此输出结果为False线程
object obj1 = new object(); object obj2 = new object(); Console.WriteLine(obj2==obj1);//引用类型比较引用 输出False
3.2 Equals3d
定义:Equals属于Object的实例方法,用于比较两个对象的引用是否相等,注意:对于Object对象比较的是引用!
然而对于值类型,类型相同(不会进行类型自动转换),而且数值相同(对于struct的每一个成员都必须相同),则Equals返回 true,不然返回false。这是为何呢? 这是由于内置的值类型都重写了Object.Equals方法,因此值类型的Equals方法与引用类型的Equals就产生了不一样的效果。
Equals在程序运行时决定比较的类型--根据对象的实际类型进行比较,根据对象的类型调用他们各自的Equals虚方法。
int i = 5; int j = 5; Console.WriteLine(i.Equals(j));//值类型比较 输出True int m = 6; double n = 6.0; Console.WriteLine(m.Equals(n));//类型不会自动转换并比较数值 输出False object obj1 = new object(); object obj2 = new object(); Console.WriteLine(obj2.Equals(obj1));//引用类型比较 输出False Console.WriteLine(obj2.Equals(string.Empty));//输出False,比较量对象的类型不一样直接返回False
3.3 ReferenceEquals
定义:Object的静态方法,比较两对象的引用是否相等,值类型和引用类型都是同样。
int i = 5; int j = 5; Console.WriteLine(object.ReferenceEquals(i, j));//输出False int m = 6; double n = 6.0; Console.WriteLine(object.ReferenceEquals(m, n));//输出False object obj1 = new object(); object obj2 = new object(); Console.WriteLine(object.ReferenceEquals(obj1, obj2));//输出False
经过以上的探讨咱们知道
ReferenceEquals比较对象的引用是否相同,并且是安全的比较
==和Equals异同
相同点: 对于值类型 都是比较代数值是否相等
不一样点:(1)对于值类型比较,==会进行类型的自动转换,而后比较代数值,Equals则不会进行转换,先比较类型,再比较值,若是类型不一样直接返回false
(2)==比较是安全的比较,也就是说两对象为任何值均可以进行比较,不会抛出异常;而Equals的比较则是不安全的,因为在Equals在运行时才会进行真正的比较,有可能调用Equals的调用者是NULL,编译经过,可是运行时则会抛出异常
因此对于引用类型是要使用实例的Equals进行比较时,必定不要忘记检查调用者对象是否为空。而Object提供的静态Equals方法也是安全的不须要检查,下面的方法等效于Object提供的静态Equals方法
public static bool AreEqual(object obj1, object obj2) { if (obj1 == null) return obj2 == null; return obj1.Equals(obj2); }
因为本人才学识浅,描述不免纰漏,若有错误,欢迎指出。么么!
参考资料:
http://www.cnblogs.com/yang_sy/p/3582946.html
http://www.cnblogs.com/zagelover/articles/2741409.html