为什么可以对硬编码字符串应用空条件运算符?

本文关键字:应用 字符串 条件运算符 编码字符 编码 为什么 | 更新日期: 2023-09-27 17:53:06

我有一个bool变量,像这样:

bool myBool = true;

如果我写if (myBool == null),我得到以下警告:

表达式的结果总是'false',因为'bool'类型的值永远不等于'bool?'类型的'null'。

这对我来说很清楚,因为检查不可空变量是否为空没有意义。Visual Studio会注意到这一点,并将其标记为警告。

现在我有一个string,默认情况下是可空的,正如我所知道的。

为什么我可以应用一个空条件操作符硬编码的string没有Visual Studio注意到它?我在想这样的事情:

"This is a string"?.AnyStringMethod();

Visual Studio不应该注意到这个string不是null吗?

为什么可以对硬编码字符串应用空条件运算符?

警告是针对看起来正确但实际上是错误的代码

你的代码看起来是错误的,但无论如何都是正确的

Visual Studio必须放弃类型

当你创建一个bool,没有办法,它可能永远是空的类型,直到你把它的类型改为bool?

然而,对于硬编码字符串,即使它的引号内有文本,也不能保证它会留在那里。被创建的"变量"(即使只是一个普通的字符串)仍然是string类型,它可以有一个null分配给它,而不改变类型。

你要找的是让它们检查它们创建的每个变量的值。如果他们要这样做,那么为什么不检查一下类似的东西呢?

var i = 0;
if (i > 2) // This will always be false!

正如InBetween在评论中提到的,这里也有一点疏忽。没有在变量中赋值的字符串(如"Some string")在功能上等同于const string s = "Some string";。如果您要这样声明它,代码检查器将检测您是否在其上运行比较,例如:

const string s = "Some String";
if (s == null) // This will give a warning that this can't happen

我将const的处理方式与普通静态字符串的处理方式的差异归因于不同的开发团队在不同的时间处理不同的部分。再说一遍,这是一种边缘情况它不会引起大问题它不会被警告没有人在处理它很可能没有想到它

因为没人想过?您的代码毫无意义,可能没有人预见到它会在生产代码中使用。我很确定这种情况在c#设计委员会中甚至没有出现过一次,尽管我对此持保留态度,直到像Eric Lippert这样的人对这个问题有了更多的了解。

c# sharp并不是生来就具有所有潜在的特性,然后有人决定删减它。为了让编译器给出某种警告,必须有人考虑它,实现它,测试它并记录它。

myBool == null的情况下,这个警告是合理的,因为它是一个貌似合理的错误,可能会出现在产品代码中,而且它显然是程序逻辑中的一个错误。第二种情况是完全无害的,即使它最终进入了生产环境,所以这个警告真的没有多大意义。

因为bool是值类型,而string是引用类型

值类型不能为空,但是通过Default

引用类型会自动为空。

Visual Studio没有注意到的原因是因为它真的不重要。这就像问蓝色是否比绿色更像一种颜色

字符串字面值与字符串对象略有不同。我相信字符串字面值基本上就像一个常量,它是不可变的,永远不会为空。

当你将字符串字面值赋值给一个变量时,你是在内存位置创建一个对该字符串的引用。该引用可以为空。如果您尝试将字符串变量与另一个字符串连接并存储回原始字符串变量,则内存中的原始字符串将被销毁,并创建一个新字符串,该字符串就是连接的字符串。这是因为字符串总是不可变的。