C#==即时窗口中的运算符的行为与运行时不同

C#==即时窗口中的运算符的行为与运行时不同,c#,equality,equals,C#,Equality,Equals,在即时窗口中尝试以下操作: object a1 = "a"; object a2 = "a"; a1==a2 // outputs false 您将看到a1==a2输出false 但是,在Windows应用程序或控制台中运行时,您将获得true: object t1 = "a"; object t2 = "a"; MessageBox.Show((t1 == t2).ToString()); // outputs true 运行时行为与=运算符和字符串的定义一致 有人知道这是否是即时窗口中的

在即时窗口中尝试以下操作:

object a1 = "a";
object a2 = "a";
a1==a2 // outputs false
您将看到
a1==a2
输出
false

但是,在Windows应用程序或控制台中运行时,您将获得
true

object t1 = "a";
object t2 = "a";
MessageBox.Show((t1 == t2).ToString()); // outputs true
运行时行为与
=
运算符和字符串的定义一致


有人知道这是否是即时窗口中的错误吗?

您所描述的是正确的行为

对象
中的
==
定义比较其参数的引用。这与
字符串的
==
实现不同,后者比较字符串的值。C#中的运算符不是虚拟的。这意味着,即使您的对象实际上是字符串,因为静态类型是
对象
,因此调用
对象
中的
==
,这意味着将进行参考比较

在C#中,字符串可以在实习生池中。通常,当您在运行时创建新字符串时,会收到对全新字符串对象的引用。要获得一个插入字符串,可以调用该方法。但是,在编译C#代码时,文本字符串会自动插入,因此如果代码中的两个位置有相同的文本字符串,则会得到对相同字符串对象的引用

在immediate窗口中,字符串显然不是interned-每次都会创建新字符串,即使它们具有相同的值。但是.NET中没有要求所有的字符串都必须被插入,所以我不认为这是一个bug。
您的代码应该避免依赖字符串是否被插入,因为这是一个实现细节。

这不是一个bug;运行时代码工作的原因是因为这些字符串是插入的(也就是说,内存中只有这些特定字符序列的一种表示形式。对常量
“a”
的每个引用都指向内存中的同一点)。在即时窗口中,将为每个对象创建一个新字符串,因此,尽管它们的内容相同,但对象指向内存中的不同位置


在引用类型上使用
=
操作符执行引用比较(除非引用的对象是特定类型,而不是对象是什么——在这种情况下,表示
对象
,而不是
字符串
——更改此行为)。因为编译后的文本字符串是内部的,所以它们具有相同的引用。因为即时窗口字符串是新字符串,它们没有相同的引用。

可能在运行时编译器会优化字符串文本以指向相同的引用位置,但是在即时窗口中,这种优化不会发生。

我建议,如果关闭优化,那么非即时版本也会返回false。如上所述,这不是一个bug,这是一个怪癖,因为在编译器中进行了优化,但在即时窗口中没有进行优化。

只是为了让OP明白:运算符不参与多态性,因此在这种情况下,使用的是
=
对象
实现,不是
字符串
实现,因此出现了这种意外行为。我不同意“correct bahavior”语句。即时窗口行为与MSDN文档和运行时不一致,甚至在设置断点并实际测试代码中存在的变量时也不一致。我个人认为微软应该解决这个问题。@Damiano:你说的“当你设置一个断点并实际测试代码中存在的变量时,即时窗口的行为与自身不一致”是什么意思?你能举个例子吗?“即时窗口行为与MSDN文档不一致”您指的是文档的哪一部分?+1,因为我从未见过即时窗口,而且它看起来很整洁!