Nullable<T>
有很多语法糖,比如:
int? parsed to Nullable<int>
int? x = null
if (x != null) // Parsed to if (x.HasValue)
x = 56; // Parsed to x.Value = 56;
还有更多。
为什么
if
条件与 Nullable 不起作用?
if (x)
{}
它出现编译器错误,指出无法将
Nullable<bool>
转换为 bool
。if (x.HasValue && x.Value == true)
或类似的东西?
这是
Nullable<bool>
最明显的用法
这是
最明显的用法Nullable<bool>
你的“明显”行为会导致许多不明显的行为。
如果
if(x)
当 x 为 null 时被视为 false,那么会发生什么
if(!x)
? 当 x 为 null 时,
!x
也为 null,因此也将被视为 false!无法通过反转来反转条件的行为,这看起来不奇怪吗?
那又如何
if (x | !x)
当然,这应该始终为真,但如果 x 为 null,则整个表达式为 null,因此为 false。
最好通过将这些不明显的情况全部定为非法来避免它们。 C# 是一种“让用户明确表达他们的意思”的语言。
我相信VB有你想要的行为。如果您喜欢的话,您可以考虑切换到 VB。
简单地说,它无法编译,因为规范说它应该编译 -
if
条件需要 boolean-expression - 并且 Nullable<bool>
类型的表达式不是 boolean-expression:
A boolean-expression 是一个产生 bool 类型结果的表达式;直接或通过在某些上下文中应用运算符 true ,如下所示。
但是,解决方法很容易:
if (x.GetValueOrDefault())
{
}
或者可能更清楚:
if (x ?? false)
{
}
后一种方法很有用,因为这意味着如果
x
为空,您可以轻松更改行为,只需将其更改为 x ?? true
即可。
null 意味着 false 并不是那么明显。空值意味着该值未知或未初始化。未知该值是 true 还是 false。谁说 null 应该表现得像 false?
Nullable<bool>
的一个更明显的用法是存储可以是 true 或 false 的内容,但有时是不相关或未知的,在这种情况下该值为 null。
我认为这不是一个好主意。
null
的计算结果为 false 感觉不自然。特别是在 if+else
陈述中。因此,强制用户明确使用:if(nb==true)
和if(nb==false)
在我看来是个好主意。
MSDN 说:
bool? b = null; if (b) // Error CS0266. { }
这是不允许的,因为不清楚 null 在条件上下文中意味着什么。使用布尔值?在条件语句中,首先检查其 HasValue 属性以确保其值不为 null,然后将其转换为 bool。有关详细信息,请参阅布尔。如果您对 bool 执行强制转换?如果值为 null,则在条件测试中将抛出 InvalidOperationException。
http://msdn.microsoft.com/en-us/library/bb384091.aspx
我的问题的一些答案为什么“bool”上没有提升短路运算符?也涉及这些方面
从技术上讲,它不起作用,因为
Nullable<T>
没有定义到 bool
的转换运算符。
实际上,由于多种原因不支持它,包括:
Nullable<T>
中会有隐式转换?T
中的每个 Nullable<T>
进行声明——当您可以将自己的类型插入编译器一无所知的 T
时,这怎么可能?if(!x)
的语义是什么?这是 Nullable 最明显的用法
要小心这样的言论。对你来说显而易见的事情不一定对其他人来说也是显而易见的。
此外,
if(x) {}
如果 x 是引用类型,也是非法的,因此为了保持一致性,Nullables 的行为应该相同。
if 语句中括号之间的任何内容都必须计算为 true 或 false。可空布尔值可以计算为 null、true 或 false。
你做不到
if (x)
{...}
出于完全相同的原因,你不能写
int? a = null;
var b = a + 1;
可空布尔值不是布尔值。在某些情况下,您想考虑 null bool?为真,有时你想将其视为假。语言设计不会为你做出这个决定。
考虑一下在这种情况下会发生什么
bool? nullBool = null;
if (nullBool)
{
someCode();
}
无法判断它是否进入了 if 语句,因为 bool 为 null 或 false。这可能是不可取的
这是因为可为 null 的 bool 不能隐式转换为 bool。这与您可以这样做的原因相同:
int x1 = 7;
int? x2 = x1;
但你不能这样做:
int? x1 = 7;
int x2 = x1;
您必须先检查它是否包含值。只能在分配值时才能使用可空类型进行隐式转换,而不能在使用该值时进行。