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

Why can I apply a null-conditional operator to a hardcoded string?

我有一个这样的 bool 变量:

bool myBool = true;

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

The result of the expression is always 'false' since a value of type 'bool' is never equal to 'null' of type 'bool?'.

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

现在我有一个 string,据我所知,默认情况下它可以为 null。

为什么我可以将空条件运算符应用于硬编码 string 而 Visual Studio 没有注意到它?我在想这样的事情:

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

Visual Studio 难道不应该注意到这个 string 根本不是空的吗?

Visual Studio 必须关闭操作员正在使用的 type

当您创建一个 bool 时,它不可能按类型为 null,除非您将该类型更改为 bool?

但是,对于硬编码字符串,即使它在引号内有文本,也不能保证它会保留在那里。创建的 "variable"(即使只是一个普通字符串)仍然是 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是引用类型

值类型不能为空,但引用类型通过默认自动为空

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

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

当您将字符串文字分配给变量时,您是在内存位置创建对该字符串的引用。该引用可以为空。如果您尝试将您的字符串变量与另一个字符串连接起来并存储回您的原始字符串变量,内存中的原始字符串将被破坏并创建一个新字符串,即连接后的字符串。这是因为字符串总是不可变的。

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

您的代码看起来不对,但无论如何都是正确的

因此:没有警告。