有区别,就是在匿名对象中的区别滴呀
var vClass1 = new { Name = "abc", Age = 20 }; var vClass2 = new { Name = "abc", Age = 20 }; var vClass3 = new { Name = "abd", Age = 21 }; Console.WriteLine(vClass1.Equals(vClass2)); //true Console.WriteLine(vClass1.Equals(vClass3)); //false Console.WriteLine(vClass1 == vClass2); //false Console.WriteLine(vClass1 == vClass3); //false
总结:对于字符串来说,两个比较的都是对象的值,并且是等效的;
对于非字符串的其他引用类型(非匿名类型)两个比较的都是对象的引用,并且是等效的;
对于匿名类型,Equal()方法比较的是类型的状态,如果两个类型的属性和值都相同,就返回true;==比较的是对象的引用。
再添加一个demo 练习代码:
using System; using System.Collections.Generic; using System.Text; namespace ConsoleApplication12 { class Program { static void Info() { object obj = 1; System.Type type = obj.GetType(); //这里存在一个饮食的转换, Console.WriteLine(type.Name); string a = "a"; System.Type type1 = a.GetType(); //String 类型的数据 Console.WriteLine(type1.Name); object b = "a"; System.Type type2 = b.GetType(); //String 类型的数据 还是存在一个隐士的转换; Console.WriteLine(type2.Name); //以上的结果就很好的解释了 object val1 = 12; object val2 = val1; val1 = 13; //返回的结果是我们 12 Console.WriteLine(val2); object o = new object(); System.Type type3 = o.GetType(); //object类型的值; Console.WriteLine(type3.Name); Console.ReadLine(); } static void Info2() { //常见的误区; string a = "a"; string b = a; b = "b"; //或者 a="b"; Console.WriteLine(a); //发现a还是等于"a"滴呀; //这样写你就理解了 /* string a = "a"; //==> a----->new String("aaa") string b = a; //==> b----->a, 传引用 b = "b"; //==> b----->new String("bbb"), 传引用,b指向了一个新的字符串,a并没有变 此时引用已经指向了一个新的地址; */ //就像这样; person p = new person(); person p1 = new person(); Console.WriteLine(p==p1); //false Console.WriteLine(string.Equals(p,p1)); //fasle Console.ReadLine(); } static void Info3() { person p = new person(); person p1 = new person(); Console.WriteLine(string.ReferenceEquals(p, p1)); //fasle string str1 = "string"; string str2 = "string"; //string 是引用类型,他们应该输出false 滴呀,但是结果却是true; bool isTrue = string.ReferenceEquals(str1,str2); Console.WriteLine(isTrue); Console.ReadLine(); /* 原理解答: str1,str2引用同一对象,节省内存,并不会为str2单独开辟内存空间。 CLR使用了一种叫字符串驻留的技术,当CLR初始化时, 会创建一个内部的散列表,其中的键为字符串, 值为指向托管堆中字符串的引用。刚开始,散列表为空, JIT编译器编译方法时,会在散列表中查找每一个文本常量字符串, 首先会查找"abc"字符串,并且因为没有找到, 编译器会在托管堆中构造一个新的指向"abc"的String对象引用, 然后将"abc"字符串和指向该对象的引用添加到散列表中。接着, 在散列表中查找第二个"abc",这一次由于找到了该字符串, 指向同一个String对象的引用会被保存在变量str2中, 到此str1和str2指向了同一个引用,所以string.ReferenceEquals(str1, str2)就会返回true了。 * * */ string value = "fuck"; Change(value); //其实传递的是原内容的拷贝 Console.WriteLine(value); //结果还是我们的string 类型的值; /* 也就是说一个字符串一旦被创建, 我们就不能再将其变长、变短、或者改变其中的任何字符 MSDN上这样解释:字符串对象是不可变的,即它们一旦创建就无法更改。 对字符串进行操作的方法实际上返回的是新的字符串对象。 */ Console.ReadLine(); } static void Change(string str) { str = "changed"; } static void Main(string[] args) { person p=new person(); p.Name = "jack"; person p1 = new person(); p1.Name = "jack"; person p2 = new person(); p2.Name = "tom"; Console.WriteLine(p==p1); Console.WriteLine(string.Equals(p,p1)); //都是不同对象,不管值是否相同,最总的比较结果都是false //但是对于命名对象的话; name p 和 p1 就是相等的呀 Console.ReadLine(); } } public class person { private string _name; public string Name { get { return _name; } set { this._name = value; } } } }
int a = 100;
long b = 100;
Console.WriteLine(object.Equals(a,b)); //先比价两个数据的类型;如果类型不相同,直接返回false;
Console.WriteLine(b.Equals(a)); //这个方式是被重写的的方法,同样是要像比较类型;如果类型相同则,比较直,如果类型不相同,先进行强制装换
//再进行比较;