我对这段代码感到困惑,这两个条件有什么区别?为什么结果不一样?
Example Number 1
- 不要使用相同的datatype
w /相同值,但会返回与 {{相同的结果1}}
true
int value1 = 'a';
char value2 ='a';
Console.WriteLine(value1 == value2);
Console.WriteLine(value1.Equals(value2));
- 它们具有相同的Example Number 2
w /相同值,但会返回 datatype
< / p>
false & true
答案 0 :(得分:10)
在您的问题看似简单的代码中实际上发生了很多事情,所以让我们一步一步地处理它。请注意,有很多事情可能会遗漏,请使用评论字段。
首先是第一段代码:
int value1 = 'a';
char value2 ='a';
Console.WriteLine(value1 == value2);
Console.WriteLine(value1.Equals(value2));
这一行:
int value1 = 'a';
应该给出一个关于此代码行为的原因的提示。存在从char
到int
的静默转换。实际上,编译的内容对于这个变量根本没有提到char
,它是一个数字。分配给int
变量的数字是a
的代码点值,即97。
第一次比较:
value1 == value2
是使用==
上的int
运算符完成的,因此实际上,完成了纯数字比较,就好像字符是数字一样。这里进行相同的静默转换,将字符转换为数字。由于它是相同的字符和相同的转换,因此您也可以从这个比较中得到97。
This is mentioned in the spec under section 6.1.2, Implicit numeric conversions:
隐含的数字转换是:
...
从char
到ushort
,int
,uint
,long
,ulong
,float
,double
或decimal
这意味着所写的内容实际上等同于:
97 == 97
第二次比较:
value1.Equals(value2)
使用完全相同的转换完成,因此您拥有:
97.Equals(97)
因此,让我们通过添加显式强制转换并将代码更改为编译器所看到的代码,使第一段代码超级清晰:
// int value1 = (int)'a'; // 97
int value1 = 97;
char value2 = 'a';
Console.WriteLine(value1 == (int)value); // 97 == 97
Console.WriteLine(value1.Equals((int)value2)); // 97.Equals(97);
我还要求LINQPad向我展示这两个陈述的反编译:
int a = 97;
int a = 'a';
他们都编译成:
ldc.i4.s 61 // 0x61 = 97
所以要清楚一点,这个静默转换是由编译器完成的,没有运行时代码将字符转换为int,用于声明,代码执行并编译,就像你实际编写了
一样int value1 = 97;
这就是这一部分的原因。
现在进入下一部分:
object obj1 = "Object One";
object obj2 = new string("Object One".ToCharArray());
Console.WriteLine(obj1 == obj2);
Console.WriteLine(obj1.Equals(obj2));
此处您首先声明两个object
变量,这很重要,然后为它们提供相同的string
值,尽管它们是两个不同的实例< / em>的
所以让我们来处理第一次比较:
obj1 == obj2
这是使用为==
定义的object
运算符完成的,该运算符会比较引用。由于我们已经确定第二个变量的时髦字符串构造构造了一个新实例,因此参考比较表明它们是不同的。
之所以使用==
上定义的object
运算符,而不是string
上定义的运算符,是因为运算符在编译时已解析 -time和编译时编译器只知道变量的类型为object
。它们包含字符串的事实,即使编译器可以&#34;看到&#34;您刚刚为其分配了字符串,因此应该使用string
==
运算符,而忽略它。
但是,当你这样做时:
obj1.Equals(obj2)
然后您调用.Equal(object other)
中声明的虚拟 object
,,string
strong>,因此你得到字符串内容比较,这表明它们是相同的。
因此,让第二段代码变得非常清晰:
object obj1 = "Object One";
object obj2 = new string("Object One".ToCharArray());
Console.WriteLine(obj1.ReferenceEquals(obj2)); // <-- changed
Console.WriteLine(obj1.Equals(obj2));
答案 1 :(得分:2)
在示例1中,int和char是值类型,因此相等比较(via ==或Equals)默认为逐位比较(如文档here所示),因为它们都不会覆盖==及其Equals实现将工作委托给==。
在两种情况下都返回true,因为value1和value2具有相同的二进制表示。
在示例2中,string是引用类型,obj1和obj2是对恰好具有相同内容的2个字符串实例的引用。
但是因为它们被声明为对象,并且在编译时解析了==,所以编译器的唯一选择是发出引用比较(= false)
相比之下,obj1.Equals实际上是对string.Equals(object)
的调用,它将返回字符串值的比较
答案 2 :(得分:1)
<强> Example1
强>
int
的值为97
,char
的值也是Example2
。 (见ASCII)
两者都是值类型,因此每次都会对值进行比较。
<强> .Equals
强>
字符串是引用类型。
所以使用==
比较值(它们是相同的)和Set srchrng = rows(Application.Match("Grand Total*", Range("A:A"), 0)).cells
比较参考,这是不同的。
答案 3 :(得分:0)
示例编号1
这里发生了Implicit Conversion,因为两者都是值类型,所以不会将引用与真实结果进行比较。为了进一步打破它,这就是发生的事情:
int value1 = 'a'; //First converts to ASCII value 97 and then stored in value1
char value2 ='a'; //Stored as a
Console.WriteLine(value1); //output is 97
Console.WriteLine(value2); //output is a
Console.WriteLine(value1 == value2); //compares using implicit conversion. Since value type, so only value comparison and hence true
Console.WriteLine('a' == 97); //compares using implicit conversion. Since value type, so only value comparison and hence true
Console.WriteLine(value1.Equals(value2)); //compares using implicit conversion. Since value type, so only value comparison and hence true
示例编号2 -
在这里,您已手动使用从Char到String的转换,因此发生了Explicit Conversion。为了进一步突破,发生了这样的事情:
object obj1 = "Object One"; //string value is stored in Object type variable
object obj2 = new string("Object One".ToCharArray()); //Explicit conversion
Console.WriteLine(obj1); //Output is Object One
Console.WriteLine(obj2); //Output is Object One
Console.WriteLine(obj1 == obj2); //Since == compares both reference and value, hence the false output
Console.WriteLine(obj1.Equals(obj2)); //Equals() compares just the value, hence the true result