【问题标题】:C# null or null-conditional operator in boolean expression [duplicate]布尔表达式中的 C# null 或 null 条件运算符
【发布时间】:2020-11-25 23:08:07
【问题描述】:

有人可以向我解释为什么会这样吗?

List<int> foo = null;
bool bar = foo?.Count > 7;

foo 为null 时,它变得等价于:

bool bar = null > 7;

IntelliSense 说 null7 都是 Nullable&lt;int&gt; 类型,但是编译器是如何决定的呢?!

此外,Nullable&lt;T&gt; 没有定义大于运算符。怎么可能?不能保证T 定义了大于运算符。

【问题讨论】:

  • 因为intNullable&lt;int&gt; 之间存在隐式转换,nullNullable&lt;int&gt;,编译器会为我们执行该转换以评估条件(两个操作数都必须是同类型)
  • Nullable 很神奇;类型上的运算符会自动提升到相应的Nullable,而无需显式运算符。语言规范有这方面的详细信息,但不是很容易理解(重载解决方案是最复杂的主题之一,要全面了解可空对象的工作原理,您必须阅读多个不同的部分)。
  • FWIW,this 是解释可空值运算符在没有明确定义的情况下如何工作的部分。
  • @Andy:除了这并不总是一个选项或并不总是正确的。 null &gt; xxint 始终是 false,但 .GetValueOrDefault() 给出 0。在这种情况下(项目计数)0 是一个完全合理的值,但当然首先允许可空值的全部原因是允许类型本身没有合理值的情况。 (另外,?? 是一个东西,所以很少有任何理由调用该方法。)
  • 好吧,对于我们这些习惯使用 SQL 和 NULL 的人来说,这种行为是显而易见的(除了与 null 比较相等/不等式时,它不像 SQL 中那样工作,而是以直接的方式工作) .与往常一样,对于被认为令人困惑或不直观的常见功能,您通常需要了解它们是如何工作的,因为没有什么能阻止其他开发人员使用它们。这不是一个不起眼的角落案例;它包含在语言中(更具体地说是 LINQ)是有原因的。无论如何,语言规范都清楚地说明了这意味着什么;你是否喜欢使用它是另一回事。

标签: c#


【解决方案1】:

正如 Rofus 和 Jeroin 在 cmets 中正确指出的那样,T 到 T 之间的转换?当您与“Null”进行比较时总是隐含的 7 变为“Nullable&lt;int&gt;

bool bar = foo?.Count > 7;

类似于 -

 int? count = null; 
 int? k = 7; // Implicit conversion here!
 var bar =  count > k;

关于&gt; 运算符的第二个问题。是的,虽然Nullable&lt;T&gt; 结构没有定义诸如&lt;&gt; 甚至== 之类的运算符,但以下代码仍然可以正确编译和执行,这与您的情况类似-

int? x = 3;
int? y = 10;
bool b = x > y;

这是因为编译器 lifts 来自底层值类型的大于运算符 -

bool b = (x.HasValue && y.HasValue) ? (x.Value > y.Value) : false;

Operator LiftingLifted Operators 表示您可以在 T? 上隐式使用 T 的运算符。编译器在处理Nullable&lt;T&gt; 类型时对不同的运算符集有不同的规则集。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-10-29
    • 1970-01-01
    • 1970-01-01
    • 2023-01-06
    • 2011-05-13
    • 2018-09-22
    • 1970-01-01
    • 2020-03-30
    相关资源
    最近更新 更多