C# == 和 Equals

正怒月神 2017-10-24 07:32:43
加精
最近在贴吧有一位朋友问了个问题,
我测试下来也不是特别明白,只是主观猜测。
先看代码

int t1 = 10;
int t2 = 10;

Console.WriteLine(t1 == t2); //True
Console.WriteLine(t1.Equals(t2)); //True


object a1 = 15;
object a2 = 15;


Console.WriteLine(a1 == a2); //False
Console.WriteLine(a1.Equals(a2)); //True

object b1 = new StringBuilder("a");
object b2 = new StringBuilder("a");
object b3 = b1;
Console.WriteLine(b1==b2); //False
Console.WriteLine(b1.Equals(b2)); //False
Console.WriteLine(b3 == b1); //True
Console.WriteLine(b3.Equals(b1)); //True


然后看看msdn对于 ==和 equals的解释:
== 的解释:

对于预定义的值类型,如果操作数的值相等,则相等运算符 (==) 返回 true,否则返回 false。 对于 string 以外的引用类型,如果两个操作数引用同一个对象,则 == 返回 true。 对于 string 类型,== 比较字符串的值。


equals的解释:

如果当前实例是引用类型,Equals(Object)方法测试引用相等性,并调用Equals(Object)方法等效于调用ReferenceEquals方法。 引用相等性意味着进行比较的对象变量引用同一个对象
如果当前实例是值类型,Equals(Object)方法测试值是否相等

其他的代码都能理解,可是那么问题来了。
为何中间一段,
object a1 = 15;
object a2 = 15;

Console.WriteLine(a1 == a2); //False
Console.WriteLine(a1.Equals(a2)); //True

产生的结果不同呢?
我看了下他们产生的地址:

发觉地址不同,值相同。
那么我主观猜测,==比较了地址,而equals比较了值。
我不确定这个猜测是否正确。但是我又没办法解释这个现象。
除非我甩锅给msdn,==和equals内部实现导致的问题?

希望有了解的朋友可以告诉一下。
...全文
7287 64 打赏 收藏 转发到动态 举报
写回复
用AI写文章
64 条回复
切换为时间正序
请发表友善的回复…
发表回复
弃笔从戎 2017-11-21
  • 打赏
  • 举报
回复
非常感谢我又学多了一点知识
Jef_Zhang 2017-11-18
  • 打赏
  • 举报
回复
这才是官方的说明啊:Object.Equals 方法
Jef_Zhang 2017-11-18
  • 打赏
  • 举报
回复
https://msdn.microsoft.com/zh-cn/library/bsc2ak47(v=vs.110).aspx
mk_lucifer 2017-11-13
  • 打赏
  • 举报
回复
Equals只是个object定义的方法,默认的class是让他们引用相等,但是根据用户需求可以继承,很多类型都是重载过的,比如Int32 ,string这些,他们不判断引用相等,而是取值相等,因为他们有override 过Equals。。。 ==对于常规值类型已经定义好了,引用类型也是默认为引用相等,但是可以运算符重载,==和Equals是两个不同的东西,而且重载==必须重载!=,他的来源在于operator ==。。。 最简单的例子 class A:object{ int b; public override bool Equals(object o) { if(o is A) { return this.b==(o as A).b; } throw Exception("Type Error"); } public static bool operator ==(A a1, A2) { return a1.b==a2.b; } } 这就是这两个东西的由来。。。。
qq_40989322 2017-11-08
  • 打赏
  • 举报
回复
good.............
DarkIsLight 2017-11-08
  • 打赏
  • 举报
回复
感谢感谢,感觉非常有用!
  • 打赏
  • 举报
回复

int t1 = 10;
            int t2 = 10;
 
            Console.WriteLine(t1 == t2);          //True    这个不解释
            Console.WriteLine(t1.Equals(t2));     //True 调用的是Int32的equals方法,都是10,true
 
 
            object a1 = 15;
            object a2 = 15;
 
 
            Console.WriteLine(a1 == a2);        //False  a1和a2是俩Int32对象(应该是可以为null的),两个对象的地址不一样,这里为false
            Console.WriteLine(a1.Equals(a2));   //True  对比的是值15,这里正确
 
            object b1 = new StringBuilder("a");
            object b2 = new StringBuilder("a");
            object b3 = b1;
            Console.WriteLine(b1==b2);          //False       俩个对象,这里肯定false
            Console.WriteLine(b1.Equals(b2));   //False   这个为啥为false,去看StringBuilder的源码,猜想:什么时候为true呢,调用Clone方法创建个副本的时候应该为true
            Console.WriteLine(b3 == b1);        //True  地址对比,true
            Console.WriteLine(b3.Equals(b1));   //True  同一对象,肯定为true
jyglint 2017-11-01
  • 打赏
  • 举报
回复
楼主的理解有些是错的,这个涉及到了c#中操作符重载这个东西
qq_40878189 2017-10-31
  • 打赏
  • 举报
回复
peterzhao2099 2017-10-29
  • 打赏
  • 举报
回复
equal需要你自己重写的 ==比较的是值
李好呀 2017-10-28
  • 打赏
  • 举报
回复
equals比较hashcode是否相等
  • 打赏
  • 举报
回复
C#也有值类型和引用类型。就是这样简单。
正怒月神 2017-10-26
  • 打赏
  • 举报
回复
引用 51 楼 xiaoxiangqing 的回复:
平时用得比较少,基本上都是用的==
我平时都很少使用Object了
正怒月神 2017-10-26
  • 打赏
  • 举报
回复
引用 49 楼 njit_77 的回复:
object a1 = 15; object a2 = 15; Console.WriteLine(a1 == a2);// a1,a2如果是同一个引用,返回true。c#语言规范5.0 Console.WriteLine(a1.Equals(a2));//这里调用object.Equal(),你可以看下我写的4.2.2Object内部的Equals函数 //最终调用System.Runtime.CompilerServices.RuntimeHelpers.Equals(a1, a2)//返回true。这个方法我目前没找到详细代码
17楼给出了解答。我认为是正确的。 你的博客我看了,观点是正确的,这和msdn说法一致。
真相重于对错 2017-10-25
  • 打赏
  • 举报
回复
.net有什么问题解释不了,看一下reflect的代码就清楚了
正怒月神 2017-10-25
  • 打赏
  • 举报
回复
引用 43 楼 u012948520 的回复:
那就没问题了,既然他是string类型,那么gettype,tostring,equals都是调用了string里面重载的函数
是的,主要还是没想到 object的equals方法针对的其实是对象本来类型 17楼说的应该准确无误了
白衣如花 2017-10-25
  • 打赏
  • 举报
回复
引用 42 楼 hanjun0612 的回复:
[quote=引用 40 楼 u012948520 的回复:] [quote=引用 18 楼 hanjun0612 的回复:] [quote=引用 17 楼 closurer 的回复:] 你的测试结果和 msdn 的说法好像并没有相悖的地方啊。 == 是静态函数,并不属于某个对象,编译器根据左右参数的类型去执行匹配的重载; Equals 是虚函数,可以在所有类型里面重写,这样即使调用的是 object 的 Equals,实际上调用的是 object 的具体对象的 Equals
即使调用的是 object 的 Equals,实际上调用的是 object 的具体对象的 Equals 这么说的话,那倒是解释的通了。老铁 [/quote]试一下object o = new object("a"); cw(0.GetType());[/quote] static void Main(string[] args) { object o = "a"; Console.WriteLine( o.GetType()); //System.String Console.ReadLine(); } 输出了System.String,怎么了?[/quote]那就没问题了,既然他是string类型,那么gettype,tostring,equals都是调用了string里面重载的函数
正怒月神 2017-10-25
  • 打赏
  • 举报
回复
引用 40 楼 u012948520 的回复:
[quote=引用 18 楼 hanjun0612 的回复:] [quote=引用 17 楼 closurer 的回复:] 你的测试结果和 msdn 的说法好像并没有相悖的地方啊。 == 是静态函数,并不属于某个对象,编译器根据左右参数的类型去执行匹配的重载; Equals 是虚函数,可以在所有类型里面重写,这样即使调用的是 object 的 Equals,实际上调用的是 object 的具体对象的 Equals
即使调用的是 object 的 Equals,实际上调用的是 object 的具体对象的 Equals 这么说的话,那倒是解释的通了。老铁 [/quote]试一下object o = new object("a"); cw(0.GetType());[/quote] static void Main(string[] args) { object o = "a"; Console.WriteLine( o.GetType()); //System.String Console.ReadLine(); } 输出了System.String,怎么了?
圣殿骑士18 2017-10-25
  • 打赏
  • 举报
回复
引用 37 楼 hanjun0612 的回复:
[quote=引用 35 楼 daixf_csdn 的回复:] 我感觉想的太多是不对的,我相信c#语言的设计,本身遵循的是一种极简的的逻辑在里边,以此为基础去理解各种变化就可以了,如果累举各种细节情况来分析,反而把自己绕进去了。 这个极简的逻辑,我的观点,补充一下上面说过的: 1.在对象化编程的世界里,本来不应该有==,equals比较值,refrenceequal比较引用,本来从逻辑上来说,就足够了,没==什么事。 2.但==确实很方便,更直观。那么我们因为便利性而使用==,可以看作语法糖,c#重写了==,使程序员在equals和refrenceequals之外,有一个更便捷的方式。但使用==的理念必须清晰,就如3所说。 3.基于以上原因,==最好理解为:以比较的类型为前提,决定比较的方式。即,值类型比较值,对象类型比较引用 以这种极简的观念出发,楼主说的15赋予两个object对象,因为object是对象基类,值被包装过了进行的对比,所以是引用比较,地址也不同。
这个问题的本身并不纠结==是特殊还是是否存在。 只是讨论对于装箱后==与equals的比较结果。 17楼闭包客回答了。我觉得这应该是正确答案了。[/quote] 他那个说法,也解释的通,我有印象,在《c#高级编程》有讲。
白衣如花 2017-10-25
  • 打赏
  • 举报
回复
引用 18 楼 hanjun0612 的回复:
[quote=引用 17 楼 closurer 的回复:] 你的测试结果和 msdn 的说法好像并没有相悖的地方啊。 == 是静态函数,并不属于某个对象,编译器根据左右参数的类型去执行匹配的重载; Equals 是虚函数,可以在所有类型里面重写,这样即使调用的是 object 的 Equals,实际上调用的是 object 的具体对象的 Equals
即使调用的是 object 的 Equals,实际上调用的是 object 的具体对象的 Equals 这么说的话,那倒是解释的通了。老铁 [/quote]试一下object o = new object("a"); cw(0.GetType());
加载更多回复(44)

110,499

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧