将 Elvis 运算符与 string.Equals 结合使用

Using Elvis operator in combination with string.Equals

我想知道为什么以下代码在 C# 6.0 中有效:
(在这个例子中 data 是一个随机 class 包含 val 作为 public 字符串)

if ("x".Equals(data.val?.ToLower()) { }

但下面这行不是:

if (data.val?.ToLower().Equals("x")) { }

Visual Studio 显示以下错误:

Cannot implicitly convert type 'bool?' to 'bool'. An explicit conversion exists (are you missing a cast?)

第一个语句正在计算 Equals 的 return 值,而第二个语句计算 bool? 可能为空。

我没有要测试的 c# 6.0,但这应该可以工作

if (data.val?.ToLower().Equals("x") ?? false) { }
if ("x".Equals(data.val?.ToLower()) { } 

最终会 return 一个布尔值,因为 Equals 调用但是这个:

if (data.val?.ToLower().Equals("x")) { }

当表达式被求值时,它将 return 一个 System.Nullable<bool> ,它不同于 bool (前者是一个可以赋值 null 的结构,而后者只能是 truefalse) if 所期望的。此外,在 C# 中,null 值不会计算为 false(根据 C# 规范)。

除了其他答案之外,我认为如果您手头写出等效代码会很有用,这样您就可以看到发生了什么。

第一行相当于:

string temp = data.val != null ? data.val.ToLower() : null;
if ("x".Equals(temp)) { }

这是完全有效且显而易见的。

第二个语句等同于:

bool? temp = data.val != null ? data.val.ToLower().Equals("x") : null;
if (temp) { } //error

这可能不太明显,但是语句 data.val?.ToLower().Equals("x") 将 return null 如果 data.valnull 否则它将 return data.val.ToLower().Equals("x") 的结果。因为语句可以 return nullbool 整个语句的类型是 bool? 但你不能在 [=22= 中使用 bool? ]直接。

正如其他人所指出的,将 bool? 转换为 bool 将解决您的问题。一种方法是使用 GetValueOrDefault():

if (data.val?.ToLower().Equals("x").GetValueOrDefault()) { }