【问题标题】:C# == operator in Immediate window behaves differently than at run-time立即窗口中的 C# == 运算符的行为与运行时不同
【发布时间】:2010-05-25 13:30:41
【问题描述】:

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

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

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

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

【问题讨论】:

  • +1 只是因为我从未见过立即窗口,它看起来很整洁!

标签: c# equality equals


【解决方案1】:

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

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

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

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

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

【讨论】:

  • 只是为了让 OP 清楚:运算符不参与多态性,所以在这种情况下,使用的是 ==Object 实现,而不是 String 实现,因此出现了这种意外行为。
  • 我不同意“正确的行为”的说法。当您放置断点并实际测试代码中存在的变量时,即时窗口行为与 MSDN 文档和运行时不一致,甚至与自身不一致。我个人认为微软应该解决这个问题。
  • @Damiano:你是什么意思:“当你放置一个断点并实际测试代码中存在的变量时,即时窗口行为与自身不一致。”?能给我举个例子吗? “即时窗口行为与 MSDN 文档不一致”您指的是文档的哪个特定部分?
【解决方案2】:

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

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

【讨论】:

    【解决方案3】:

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

    【讨论】:

      【解决方案4】:

      我建议如果您关闭优化,那么非即时版本也将返回 false。如前所述,这不是一个错误,它是一个怪癖,因为优化发生在编译器内,而不是在即时窗口内。

      【讨论】:

        猜你喜欢
        • 2021-02-24
        • 2012-12-03
        • 1970-01-01
        • 2017-01-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-12-08
        • 2017-01-17
        相关资源
        最近更新 更多