“==” 是比较两个变量的值相称。
Equals是比较两个变量是不是指向同一个对象。
如:这篇文章,并以这篇文章中的例子为例。
public class Person { public Person(string name) { this.Name = name; } public string Name { get; set; } } static void Main(string[] args) { string a = new string(new char[] { 'h', 'e', 'l', 'l', 'o' }); string b = new string(new char[] { 'h', 'e', 'l', 'l', 'o' }); Console.WriteLine(a == b); //true Console.WriteLine(a.Equals(b)); //true object g = a; object h = b; Console.WriteLine(g == h); //false Console.WriteLine(g.Equals(h)); //true Person p1 = new Person("jia"); Person p2 = new Person("jia"); Console.WriteLine(p1 == p2); //false Console.WriteLine(p1.Equals(p2)); //false Person p3 = new Person("jia"); Person p4 = p3; Console.WriteLine(p3 == p4); //true Console.WriteLine(p3.Equals(p4)); //true Console.ReadKey(); }
假如上述结论准确,“==” 是比较两个变量值相称,那末下面这句代码就不应该为True.
Console.WriteLine(a == b); //true
很明显,上面的两个字符串变量:a,b 是指向两个差别的对象,即它们在栈空间存储的内存地点也是差别的。但为毛它们就相称了呢?
2.什么是运算符重载?
运算符重载,就是对已有的运算符从新举行定义,给予其另一种功用,以顺应差别的数据范例。打个简朴的比如:“+” 运算符,在“+” 两
边全为数值范例的变量时,“+” 运算符示意数学上的“+” 意义。若“+” 运算符双方只需有一个为字符串范例,那末“+” 运算符就示意衔接
字符串的意义。如许的运算符重载实例有许多,那末这跟本文主题有毛关联?我想说的是,上面字符串变量:a , b 就是由于String类
重载了运算符 “==”,看以下源代码:
public static bool operator == (String a, String b) { return String.Equals(a, b); } public static bool operator != (String a, String b) { return !String.Equals(a, b); }
很明显String类中真的重载了“==”运算符,而且不止 “==” 另有 “!=” 哦。而且在重载运算符要领内部直接挪用String类中的Equals要领,
源代码以下:
public static bool Equals(String a, String b) { if ((Object)a==(Object)b) { return true; } if ((Object)a==null || (Object)b==null) { return false; } if (a.Length != b.Length) return false; return EqualsHelper(a, b); }
由上可得:“==” 运算符并不一定是比较两个变量中存储的值是不是相称,这要看当前运算符在当前这个范例中是不是写有重载。
3.Equals的重写
照样上面例子:
string a = new string(new char[] { 'h', 'e', 'l', 'l', 'o' }); string b = new string(new char[] { 'h', 'e', 'l', 'l', 'o' }); Console.WriteLine(a == b); //true Console.WriteLine(a.Equals(b)); //true
由上可知:a ,b 为两个差别的对象。但Equals为True,则上述:“Equals是比较两个变量是不是指向同一个对象“这一结论不成立。缘由
看String类中的Equals要领:
public override bool Equals(Object obj) <br> { if (this == null) //this is necessary to guard against reverse-pinvokes and throw new NullReferenceException(); //other callers who do not use the callvirt instruction String str = obj as String; if (str == null) return false; if (Object.ReferenceEquals(this, obj)) return true; if (this.Length != str.Length) return false; return EqualsHelper(this, str); } public bool Equals(String value) <br> { if (this == null) //this is necessary to guard against reverse-pinvokes and throw new NullReferenceException(); //other callers who do not use the callvirt instruction if (value == null) return false; if (Object.ReferenceEquals(this, value)) return true; if (this.Length != value.Length) return false; return EqualsHelper(this, value); }
由上面可知String类中不仅重写了Object中的Equals另有本身的Equals要领,然则完成代码几乎是一样的。比较范例,内存地点,
现实值,从而取得终究的效果。所以Equals不一定就是单一的比较援用地点是不是雷同,更何况我们还能够重写和自定义。然则重写
Equals也有须要注重的处所,就是假如你须要用到HashMap,HashSet,Hashtable那末你也须要重写GetHashCode()。
4.为何有了“==”还要有Equals?
中国有一句话:“任何事物的存在必定有他存在的原理和代价”,同理“==”和Equals也是一样。“==” 在援用范例中最基础的完成就是去比
较两对象的内存地点是不是一致,一致则相称反之则不等。如许的完成很明显是从硬件角度去思索的,假如两个对象相称即为同一个对象,
那末它们在内存中的地点必定相称。但许多时刻 “行动(要领)“ 是取决于我们去视察天下的角度。 如:String范例我们说明一个字符
串更在乎的是字符串所具有的现实值,而不是在乎两个对象在内存中是建立了一次照样两次(即内存地点是不是相称),只需它们所具有的
现实值是相称的那末我们就以为它们是相称,这是从生活营业逻辑中去明白的而不是从机械角度上去明白的。固然上面声明雷同的字符串
变量是建立一次照样两次我想:” 常量池(或字符串拘留池)“ 已给了我们最好的解决方案。
5.“==”和Equals究竟什么关联?
”==“ 运算符和Equals它们现实上是互补关联。由于:”==“ 运算符重要完成情势是站在 ”计算机角度(或者说硬件角度)” 上去完成的,
而Equals是站在经常使用的营业场景或者是特定的营业场景下去完成的,两者没有什么必定的联络,是依据本身的营业须要挑选差别要领罢了。
所以Object内里的Equals是Visual,许多类中都重写了它,并真正达了在当前范例中所需的特定行动,即:多态。所以就不难诠释上面:
object g = a; object h = b; Console.WriteLine(g == h); //false Console.WriteLine(g.Equals(h)); //true
由于Object中没有完成重载运算符:“==”,所以当前“==”的比较体式格局是比较两变量在栈空间存储的内存地点是不是雷同。而Equals则是
挪用String类中的Equals,缘由g变量在运转中它现实上指向一个字符串对象的,而当前的Object范例只是Visual studio和编译器的行动,即:照样多态。
末了任何东西都有它的划定规矩:”==“和Equals也不破例,细致资料请点击:跳转至MSDN。
以上就是浅析C#中的“==”和Equals的示例代码的细致内容,更多请关注ki4网别的相干文章!