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

时间:2016-06-28 12:33:52

标签: c# string visual-studio-2015 null-conditional-operator

我有一个bool变量,如下所示:

bool myBool = true;

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

  

表达式的结果总是“假”,因为类型'bool'的值永远不会等于'bool'类型的'null'。

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

现在我有一个string,默认情况下可以为空,我知道。

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

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

Visual Studio是否应该注意到此string根本不为空?

5 个答案:

答案 0 :(得分:9)

警告适用于看起来正确但实际上是错误的代码

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

因此:没有警告。

答案 1 :(得分:8)

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的方式与处理普通静态字符串的方式之间的差异可归因于在不同时间处理不同部分的不同开发团队。同样,这是一个边缘案例,不会引起巨大的问题,它不会被警告,没有人在其上工作很可能没有考虑它。

答案 2 :(得分:1)

因为没人想过吗?你的代码是如此毫无意义,以至于没有人预见到它会被用在生产代码中。我非常确定这种情况在C#设计委员会中甚至没有出现过一次,尽管我有点喜欢这样,直到像Eric Lippert这样的人对这个问题有了更多了解。

C#sharp并不是天生具有所有潜在功能,然后有人决定修剪它。为了让编译器发出某个警告,有人必须考虑它,实现它,测试它并记录它。

myBool == null的情况下,警告是合理的,因为它是一个看似合理的错误,可能会使其成为生产代码,而且它显然是程序逻辑中的一个错误。第二种情况是完全无害的,即使它最终投入生产,所以警告确实没有多大意义。

答案 3 :(得分:0)

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

值类型不能为null,但引用类型会通过Default

自动清零

Visual Studio没有注意到的原因是因为它真的没有可重复性......就像问蓝色是否比绿色更多

答案 4 :(得分:0)

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

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