问题描述
objectg=a;objecth=b;Console.WriteLine(g==h);执行结果是falseConsole.WriteLine(g.Equals(h));执行结果是trueobject是引用类型,==是比较引用类型是否是对同一个对象的引用,那g和h中存的是a和b在堆中的地址,执行结果是falseequal是比较的是两个对象的内容是否一致,那对象的内容是a和b,应该不一致,是false才对?Personp1=newPerson("jia");Personp2=newPerson("jia");Console.WriteLine(p1==p2);执行结果是falseConsole.WriteLine(p1.Equals(p2));执行结果是false==是比较引用类型是否是对同一个对象的引用,那执行结果应该是falseequal是比较的是两个对象的内容是否一致,那都是("jia"),那执行结果应该是true才对?
解决方案
解决方案二:
==对于引用类型(非字符串),永远是比较引用,没办法重写==equals可以重写。重写后可以实现自己的比较逻辑。
解决方案三:
如果姓名相同,就算同个人的话,可以这样:publicclassPerson{publicstringName{get;set;}#region重载EqualspublicoverrideboolEquals(objectobj){if(obj!=null&&objisPerson){returnName==((Person)obj).Name;}returnfalse;}publicoverrideintGetHashCode(){returnName.GetHashCode();}#endregion#region重载==publicstaticbooloperator==(Personp1,Personp2){if(((object)p1)!=null||((object)p2)!=null){if(!string.IsNullOrEmpty(p1.Name)&&!string.IsNullOrEmpty(p2.Name)){returnp1.Name==p2.Name;}}returnfalse;}publicstaticbooloperator!=(Personp1,Personp2){return!(p1==p2);}#endregion}
解决方案四:
引用类型重载后,Equal运算可以比对不同类型的的对象,比如用Person的实例和Employee的实例那怕它们之间没有继承关系,也可以按你想要的逻辑进行Equal的运算,而==不行。
解决方案五:
引用楼主u011724677的回复:
objectg=a;objecth=b;Console.WriteLine(g==h);执行结果是falseConsole.WriteLine(g.Equals(h));执行结果是true
如果你不贴出a和b的具体内涵,就不能随便说后者一定打印true。你测试一下inta=1;intb=2;objectg=a;objecth=b;Console.WriteLine(g==h);//执行结果是falseConsole.WriteLine(g.Equals(h));
解决方案六:
不知道你Person是怎么定义,如果没有重载Equals,则你的结果可能就有问题。采用以下测试代码及结果为:varp1=new{name="jia"};varp2=new{name="jia"};Console.WriteLine(p1==p2);//FalseConsole.WriteLine(p1.Equals(p2));//True
解决方案七:
你的代码实际上跟运算符重载没有关系,你使用了“弱类型”,那么你就丧失了类型系统的优点。这个时候,仅仅有Equals能帮上一点忙。例如usingSystem;namespaceConsoleApplication1{classProgram{staticvoidMain(string[]args){vara=new马{齿龄=8};varb=new香蕉{成熟度=96};objectg=a;objecth=b;Console.WriteLine(g==h);//执行结果是falseConsole.WriteLine(g.Equals(h));Console.WriteLine("按任意键结束.....");Console.ReadKey();}}class马{publicint齿龄;publicoverrideboolEquals(objectobj){vara=objas香蕉;if(a!=null)returna.成熟度==this.齿龄*12;returnbase.Equals(obj);}}class香蕉{publicint成熟度;}}
在这个例子中,当通过“马”来调用Equals的时候,一匹马可以等于一只香蕉。但是假设是强类型的,那么就可以真正让==运算符重载。例如代码usingSystem;namespaceConsoleApplication1{classProgram{staticvoidMain(string[]args){vara=new香蕉{成熟度=96};varb=new马{齿龄=8};Console.WriteLine(a==b);Console.WriteLine("按任意键结束.....");Console.ReadKey();}}class马{publicint齿龄;}class香蕉{publicint成熟度;publicstaticbooloperator==(香蕉x,马b){returnx.成熟度==b.齿龄*12;}publicstaticbooloperator!=(香蕉x,马b){return!(x==b);}}}
这里,强类型系统就能使得==运算符具有业务表现力了(而不是纠结什么对象的指针了)。在编程设计中,我们应该尽可能禁止声明object弱类型,应该把变量声明为强类型(包括接口)的。应该尽量删除弱类型代码。
解决方案八:
通常我们看到你的这种g和h的变量声明,会第一时间删除掉。因为就算是你不知道最终具体类型,你可以把g和h声明为“父类”或者“接口”,为什么滥用object呢?当你滥用object,你觉得随后的代码就“万能”了,而实际上这个时候就埋下定时炸弹了。比如说代码inta=1;stringb="2";//这里不小心把类型搞错了objectg=a;objecth=b;Console.WriteLine(g==h);//执行结果是falseConsole.WriteLine(g.Equals(h));
你要是在最后发现程序运行得一塌糊涂时,才去找为什么数据混乱、甚至崩溃,在这个只有5行代码的地方你也许觉得“方便”,但是在一个实际的项目中,那就是灾难,就是无数次在开发中无法发现、在用户面前才丢人现眼的教训,才能让你反思出来要从一开始就把变量g和h声明为强类型的!基本上都应该禁用弱类型。那种故意认为“越是object类型代码越万能”的做法,其实是成事不足的编程习惯。此外,我以前对于强类型也回复过一个帖子。其中在最后也有一个“句子”的例子,代码是这样的:句子clause=(主语)s1+(谓语)s2+(宾语)s3;
说明强类型声明,可以用来“成文自明”地表达更好的程序。
解决方案九:
==和Equals都可以重写,所以区别要看具体的实现
解决方案十:
看过许多的文章描述==与Equals的区别,基本都没怎么去深究过只是尽量保持在“普通”变量类型进行==的判断,尽量小心在对象与引用之间的判断
解决方案十一:
http://www.jb51.net/article/37212.htm不深究这种问题。
解决方案十二:
正常的,一个是地址相同,一个是值相同
解决方案十三:
引用7楼sp1234的回复:
通常我们看到你的这种g和h的变量声明,会第一时间删除掉。因为就算是你不知道最终具体类型,你可以把g和h声明为“父类”或者“接口”,为什么滥用object呢?当你滥用object,你觉得随后的代码就“万能”了,而实际上这个时候就埋下定时炸弹了。比如说代码inta=1;stringb="2";//这里不小心把类型搞错了objectg=a;objecth=b;Console.WriteLine(g==h);//执行结果是falseConsole.WriteLine(g.Equals(h));你要是在最后发现程序运行得一塌糊涂时,才去找为什么数据混乱、甚至崩溃,在这个只有5行代码的地方你也许觉得“方便”,但是在一个实际的项目中,那就是灾难,就是无数次在开发中无法发现、在用户面前才丢人现眼的教训,才能让你反思出来要从一开始就把变量g和h声明为强类型的!基本上都应该禁用弱类型。那种故意认为“越是object类型代码越万能”的做法,其实是成事不足的编程习惯。此外,我以前对于强类型也回复过一个帖子。其中在最后也有一个“句子”的例子,代码是这样的:句子clause=(主语)s1+(谓语)s2+(宾语)s3;
说明强类型声明,可以用来“成文自明”地表达更好的程序。
另外求解的类名太长的或者是NEW,喜欢用var,这算不算坏习惯?求解答
解决方案十四:
你要说a和b是什么,我才能告诉你g.Equals(h)为什么是true至于你的标题,对于引用类型,引用类型知道吧?equal表示值相等,==表示引用相等比如objecta=newcar("abc");objectb=newcar("abc");他们的值是相等的,用equal就是true,但是他们的引用不一样(有两个car),==为false
解决方案十五:
自己看源码啊
解决方案:
ReferenceEquals专门比较地址Equals和==,对于值类型,比较内容;对于引用类型,比较地址-------------------------objectg=a;objecth=b;Console.WriteLine(g==h);执行结果是falseConsole.WriteLine(g.Equals(h));执行结果是true按照你的输出结果,那么a,b两个对象中存储着相同的内容,但对应着2个地址,如objecta=newmyClass("abc");objectb=newmyClass("abc");这样,两个new就是2个地址,分别赋值给g,h,那么g,h也就是地址不同,内容相同--------------------------------Personp1=newPerson("jia");Personp2=newPerson("jia");Console.WriteLine(p1==p2);执行结果是false2个new出来的,地址一定不同Console.WriteLine(p1.Equals(p2));执行结果是false。按理论,应该是true!