【问题标题】:Quick watch shows that object equal to empty string is not empty string快速观看显示等于空字符串的对象不是空字符串
【发布时间】:2016-05-21 10:43:53
【问题描述】:

为什么快速观察显示语句 p == "" 为 false,但我们要进入 if 语句。

    static void Main(string[] args)
    {
        string q = "";

        A(q);
    }

    static void A (object p)
    {
        if(p == null || p =="")
        {
            Console.WriteLine("Debugger shows false");
        }
    }

这是一个错误吗?

请注意,根据Compare string and object in c# p == "" 仍应评估为true,因为"" 是一个内部字符串 - 这确实在执行代码时发生,但在快速监视中失败。

【问题讨论】:

  • 看看 ide 中的绿色曲线。这个警告是有原因的。 :)

标签: c#


【解决方案1】:

由于p 被声明为object,它使用引用相等,而不是值相等。问题是编译器将“实习”字符串文字以节省内存,所以当你这样做时

string q = ""

编译器使用对内存中的实习字符串的引用。稍后当你这样做时

if(p == "")

编译器已经对字符串进行了interned,并且使用了相同的引用,所以引用相等在这里也返回true。

QuickWatch 窗口未使用内部字符串引用,因此引用p 和字符串""不同 引用,并且语句的计算结果为false

正确的是比较字符串值是使用Equals,它被覆盖并且总是使用值相等:

if(p == null || p.Equals(""))  // should evaluate to "true" in both places.

或者只是

if(string.IsNullOrEmpty(p))

编译器会警告您这个常见错误;如果您将鼠标悬停在 IDE 中的绿色下划线上,您将看到警告消息。

【讨论】:

  • 同意,这一定是快速观看工具中的一个错误
  • @chomba 不,比较字符串的正确方法是使用Equals。这是程序中的一个错误,幸运地返回了预期的结果。
  • 我明白了,所以从某种意义上说它是 QuickWatch 工具的一个限制,它无法知道运行时将执行的内存优化对吗?
  • 这是 C# 团队的 Eric Lippert 撰写的一篇关于此主题的精彩文章 blogs.msdn.microsoft.com/ericlippert/2009/09/28/…
  • @chomba 不,它突出了您通过引用相等比较字符串的问题。您永远不应该依赖字符串实习,因为它是运行时优化而不是保证。改为使用值比较方法,您将在所有地方获得正确的行为。
【解决方案2】:

这里是字符串类的链接:

https://msdn.microsoft.com/en-us/library/362314fe.aspx

object 和 string 都是引用类型,但 string 对待相等运算符的方式不同,如链接中所述。

另外,我使用 string.IsNullOrEmpty(string) 来检查字符串是否为空或空。

【讨论】:

  • p == " " 是假的。您正在将 p 的引用与空字符串的引用进行比较。
  • 您将一个空字符串与一个对象进行比较,而不是另一个字符串。您需要将对象转换为字符串,因此它将进行字符串比较而不是引用比较。我粘贴的链接中对此进行了说明。
  • 你是对的;问题是字符串是 interned,所以在编译的程序中它们是相同的引用,但在 QuickWatch 窗口中却不是。
【解决方案3】:

我认为你可以使用

(string.IsNullOrEmpty(p.ToString()))

【讨论】:

  • 我认为 p 是 object 。然后转换为字符串 p.ToString();您正在将对象与字符串进行比较是 "" 。您无法将对象与字符串进行比较
猜你喜欢
  • 1970-01-01
  • 2016-04-19
  • 1970-01-01
  • 2018-05-23
  • 1970-01-01
  • 2011-03-22
  • 2011-08-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多