我尝试使用代码使用==
和Equals
进行数字比较:
Console.WriteLine( (int)2 == (double)2.0 );
Console.WriteLine( ( (int)2 ).Equals( (double)2.0) );
Console.WriteLine((float)2.0 == (double)2.0);
Console.WriteLine( ( (float)2.0 ).Equals( (double)2.0 ) );
结果:
true
false
true
false
int, double, float
全部是ValueType
,在阅读了帖子 Here1 和 Here2 之后,我仍然无法理解为什么==
和Equals
结果不同,
这4个案例中==
和Equals
背后的工作细节是什么?
(如果这个问题重复,请告诉我)
编辑: 4个更有趣的案例:
double,float< - > INT
Console.WriteLine((double)2.0 == (int)2); //True
Console.WriteLine(((double)2.0).Equals((int)2)); //True
Console.WriteLine((float)2.0 == (int)2.0); //True
Console.WriteLine(((float)2.0).Equals((int)2.0)); //True
double,int< - >浮
Console.WriteLine((double)2.0 == (float)2.0); //True
Console.WriteLine(((double)2.0).Equals((float)2.0)); //True
Console.WriteLine((int)2 == (float)2.0); //True
Console.WriteLine(((int)2).Equals((float)2.0)); //False
答案 0 :(得分:4)
来自MSDN:
ValueType.Equals指示此实例和指定对象是否相等。
和
返回值:
类型:System.Boolean
如果obj和此实例属于同一类型且代表相同值,则为
;否则,假。*
如果你这样做:
int a = 1;
double b = a;
bool check = a.Equals(b);
您正在调用此Equals的实现:
[__DynamicallyInvokable]
public override bool Equals(object obj)
{
if (!(obj is int))
return false;
return this == (int) obj;
}
如果你这样做:
int a = 1;
int b = a;
bool check = a.Equals(b);
你在呼唤另一个人:
[NonVersionable]
[__DynamicallyInvokable]
public bool Equals(int obj)
{
return this == obj;
}
答案 1 :(得分:3)
(int)2 == (double)2.0
和(float)2.0 == (double)2.0
。实际上,它不会比较后备数据类型,而是比较编译器看到的值(因此2==2
)。即使这样,==
/ float
上的int
也会进行隐式类型转换。
虽然Equals
方法在运行时运行where types are different,因此该方法返回false
。
答案 2 :(得分:3)
(int)2 == (double)2.0 - True because the compiler promotes int to double when comparing via ==.
((int)2).Equals( (double)2.0) - False because this is calling int.Equals(object) and the types are different.
(float)2.0 == (double)2.0 - True because the compiler promotes float to double when comparing via ==.
((float)2.0).Equals((double)2.0) - False becaue this is calling float.Equals(object) and the types are different.
(double)2.0 == (int)2 - True because the compiler promotes int to double when comparing via ==.
((double)2.0).Equals((int)2) - True because there exists double.Equals(double) and the compiler
promotes the integer parameter 2 to double to call double.Equals(2.0).
(float)2.0 == (int)2.0 - True because the compiler promotes int to float when comparing via ==.
((float)2.0).Equals((int)2.0) - True because there exists float.Equals(float) and the compiler
promotes the integer parameter 2 to float to call float.Equals(2.0f).
(double)2.0 == (float)2.0) - True because the compiler promotes float to double when comparing via ==.
((double)2.0).Equals((float)2.0) - True because there exists double.Equals(double) and the compiler
promotes the float parameter 2.0f to double to call double.Equals(2.0).
(int)2 == (float)2.0 - True because the compiler promotes int to float when comparing via ==.
((int)2).Equals((float)2.0) - False because this is calling int.Equals(object) and the types are different.
请注意,在返回false
的情况下,这是因为尽管存在int.Equals(int)
,但编译器无法调用它,因为没有从浮点类型到int
的自动类型转换。
答案 3 :(得分:2)
==
是一个运算符,编译器将首先应用隐式转换以在需要时扩展其中一个操作数。
1.0 == 1
=> 1.0 == 1.0
=> true
Equals()方法不会触发隐式转换,因此返回false。它也更昂贵,需要拳击操作。它检查的第一件事就是操作数是否属于同一类型。
(1.0).Equals(1)
=> Double(1.0).Equals(object(1))
=> Double == Int32
=> false
答案 4 :(得分:0)
作为普通数字,==
比较值。使用.Equals
方法时,它们被视为object
的实例,因此.Equals
将类型视为不同,条件失败。
您希望它给出true,但类型检查条件在值比较之前。
答案 5 :(得分:0)
感谢大家的回答,他们都是好的信息,让我找到每种类型的Equals
方法文档。
在与==
相关的所有情况下都是如此,与Equals
相关的案例是:
Console.WriteLine( ( (int)2 ).Equals( (double)2.0) ); //False
Console.WriteLine( ( (float)2.0 ).Equals( (double)2.0 ) ); //False
Console.WriteLine(((double)2.0).Equals((int)2)); //True
Console.WriteLine(((float)2.0).Equals((int)2.0)); //True
Console.WriteLine(((double)2.0).Equals((float)2.0)); //True
Console.WriteLine(((int)2).Equals((float)2.0)); //False
和equals方法MSDN链接:Double,Int32,Float(Single)
在方法描述中,Equals方法的格式均为:
public bool Equals(double obj)
public bool Equals(int obj)
public bool Equals(float obj)
所以我想在使用Equals时,首先会转换等待比较的值,关键点是是否可以转换类型而不会被截断或舍入。
这里对应6个案例:
// double cannot implicit convert to int -> F
Console.WriteLine( ( (int)2 ).Equals( (double)2.0) ); //False
// double cannot implicit convert to float -> F
Console.WriteLine( ( (float)2.0 ).Equals( (double)2.0 ) ); //False
// int can implicit convert to double -> T
Console.WriteLine(((double)2.0).Equals((int)2)); //True
// int can implicit convert to float -> T
Console.WriteLine(((float)2.0).Equals((int)2.0)); //True
// float can implicit convert to double -> T
Console.WriteLine(((double)2.0).Equals((float)2.0)); //True
// float cannot implicit convert to int -> F
Console.WriteLine(((int)2).Equals((float)2.0)); //False
编辑并纠正:
通过转到VS中的定义Funciton,True Case全部转到Equals(double/float/int obj)
,错误案例全部转到Equals(object obj)
,并在Equals(object obj)
的描述中:
Returns:
true if obj <is an instance of Int/Float/Double> and <equals the value> of this instance;
otherwise, false.
所以我猜如果隐式转换失败,它会转到Equals(object obj)
并在类型检查时变为false。