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

时间:2010-05-25 13:30:41

标签: c# equality equals

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

object a1 = "a";
object a2 = "a";
a1==a2 // outputs false

您会看到a1 == a2输出false

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

object t1 = "a";
object t2 = "a";
MessageBox.Show((t1 == t2).ToString()); // outputs true

运行时行为与==运算符和字符串的定义一致。

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

4 个答案:

答案 0 :(得分:15)

您所描述的是正确的行为。

==Object的定义会比较其参数的引用。这与== String的实现不同,object比较字符串的。 C#中的运算符不是虚拟的。这意味着即使您的对象实际上是字符串,因为静态类型为==Object的{​​{1}}也会被调用,这意味着将进行参考比较。

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

在即时窗口中,字符串显然没有实现 - 每次都会创建新字符串,即使它们具有相同的值。但是.NET中没有要求所有字符串都必须被实现,所以我不认为这是一个错误。

您的代码应该避免依赖于字符串是否被实现,因为这是一个实现细节。

答案 1 :(得分:2)

这不是一个错误;运行时代码工作的原因是因为这些字符串是内部的(即,内存中只有一个特定字符序列的表示。对常量"a"的每个引用都指向内存中的相同点)。在即时窗口中,为每个字符串创建一个新字符串,因此当它们的内容相同时,对象将指向内存中的不同位置。

在引用类型上使用==运算符执行引用比较(除非引用特定类型作为对象,而不是对象 - 意味着{{1}在这种情况下,不是object - 改变了这种行为)。因为编译的文字字符串是实习的,所以它们具有相同的引用。因为直接窗口字符串是新字符串,所以它们没有相同的引用。

答案 2 :(得分:2)

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

答案 3 :(得分:0)

我建议如果你关闭优化,那么NON-immediate版本也会返回false。如上所述,这不是一个错误,由于编译器中发生的优化而不是在即时窗口内的优化,这是一个怪癖。