使用“!=”运算符比较字符串为什么会得到不同的结果?

5
我知道这可能听起来是一个非常愚蠢的问题,但我在这个问题上已经没有答案了。我们的其中一个用户最近报告了一个错误,我意识到一段旧代码正在使用`!= string.Empty`而不是`IsNullOrEmpty()`。我用`IsNullOrEmpty()`修复了它,并且现在可以正常运行,但我想真正理解这个问题。
问题是,完全相同的代码在某些机器上运行方式不同。基本上我有一个对象:`context["MODE"]`,它应该是空的。我添加了一些测试来记录:
        contextBuilder.AppendLine("MODE: |" + context["MODE"] + "|");
        contextBuilder.AppendLine("MODE != string.Empty: " + (context["MODE"] != string.Empty));
        contextBuilder.AppendLine("MODE TRIM != string.Empty: " + (context["MODE"].ToString().Trim() != string.Empty));
        contextBuilder.AppendLine("MODE.IsNullOrEmpty: " + string.IsNullOrEmpty(context["MODE"].ToString()));
        contextBuilder.AppendLine("MODE.TRIM.IsNullOrEmpty: " + string.IsNullOrEmpty(context["MODE"].ToString().Trim()));

这里是有关该字段细节的日志记录:
MODE: || 
MODE != string.Empty: False  
MODE TRIM != string.Empty: False 
MODE.IsNullOrEmpty: True  
MODE.TRIM.IsNullOrEmpty: True

以下是他的日志记录:
MODE: ||
MODE != string.Empty: True
MODE TRIM != string.Empty: False
MODE.IsNullOrEmpty: True
MODE.TRIM.IsNullOrEmpty: True

正如您所看到的,存在一个区别:MODE != string.Empty对于我来说是False(有意义),但对他来说是True!显然,MODE不是null(否则.ToString()会失败)。使用IsNullOrEmpty修复了问题,但我正在尝试弄清楚为什么会在某些用户的计算机上工作而在其他人的计算机上不工作。通常情况下,在我的测试中,有些人没有问题,其他人有问题。

我真的不明白我可以从中学到什么。为什么他的模式与null和String.Empty不同,但IsNullOrEmpty返回true?还请注意,trim实际上也是string.Empty

谢谢!


1
"IsNullOrEmpty" 实际上是通过将 "Length" 与 0 进行比较来执行空部分。 - juharr
1
还可以尝试打印出 context["Mode"].GetType().Name - juharr
你能提供关于context["MODE"]值的更多细节吗?此外,你是否确保两台机器上的.NET版本相同? - Kevin Burdett
context["MODE"] 在两种情况下都是封装在 object 中的 string。是的,这两台机器都运行相同的 .NET 框架! - Damascus
1个回答

4
如果您使用ToString(),这表明context["MODE"]的类型是object。如果您使用!=比较对象和字符串,则比较的是字符串引用而不是实际字符串值。
因此,“his mode”是一个空字符串,它与string.Empty不是同一个引用。
不要对字符串使用引用比较;在使用==!=之前,始终确保两侧都是string类型。
请注意,C#编译器应该会警告您:可能是无意中的引用比较。详情请参考:CS0252: Possible unintended reference comparison

@clcto 这是正确的输出,因为不等于 String.Empty 返回了 false,意味着它与 String.Empty 相等。 - Setsu
就像我之前所说,这是一段旧的代码,是由在我加入公司之前负责该应用程序的人编写的(是的,他错过了一个警告!)。我很好奇他的结果为什么会是这样?他的输入为空,但与string.Empty不具有相同的引用。然而,当我对其进行修剪时,它具有相同的引用!这怎么可能发生? - Damascus
Trim() 的返回类型是 string,因此编译器在这种情况下使用值比较。 - Daniel

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接