可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
There is a lot of syntax sugar with Nullable<T>
like those:
int? parsed to Nullable<int>
int? x = null
if (x != null) // Parsed to if (x.HasValue)
x = 56; // Parsed to x.Value = 56;
And more.
Why if
condition with Nullable doesn't work?
if (x)
{}
It gets Complier error saying can't convert Nullable<bool>
to bool
.
Why it's not being parsed to if (x.HasValue && x.Value == true)
or something similar?
It's the most obvious usage for Nullable<bool>
回答1:
It's the most obvious usage for Nullable<bool>
Your "obvious" behaviour leads to many inobvious behaviours.
If
if(x)
is treated as false when x is null, then what should happen to
if(!x)
? !x
is also null when x is null, and therefore will be treated as false also! Does it not seem strange that you cannot reverse the behaviour of a conditional with an inversion?
What about
if (x | !x)
Surely that should always be true, but if x is null then the whole expression is null, and therefore false.
It is better to avoid these inobvious situations by simply making them all illegal. C# is a "make the user say what they mean unambiguously" language.
I believe that VB has the behaviour you want. You might consider switching to VB if this is the sort of thing you like.
回答2:
Simply put, it fails to compile because the specification says it should - an if
condition requires a boolean-expression - and an expression of type Nullable<bool>
isn't a boolean-expression:
A boolean-expression is an expression that yields a result of type bool; either directly or through application of operator true in certain contexts as specified in the following.
However, it's easy to work round:
if (x.GetValueOrDefault())
{
}
Or to possibly be clearer:
if (x ?? false)
{
}
The latter approach is useful as it means you can easily change the behaviour if x
is null, just by changing it to x ?? true
.
回答3:
It's not that obvious that null should mean false. A null value means that the value is unknown or uninitialized. It's unknown whether the value is true or false. Who said null should behave like false?
A more obvious usage for Nullable<bool>
is to store something that can be either true or false, but sometimes is irrelevant or unknown, in which case the value is null.
回答4:
I think that wouldn't be a good idea. That null
evaluates to false doesn't feel natural. Especially in if+else
statements. So forcing the user to be explicit with: if(nb==true)
and if(nb==false)
is a good idea IMO.
MSDN says:
bool? b = null;
if (b) // Error CS0266.
{
}
This is not allowed because it is unclear what null means in the context of a conditional. To use a bool? in a conditional statement, first check its HasValue property to ensure that its value is not null, and then cast it to bool. For more information, see bool. If you perform the cast on a bool? with a value of null, a InvalidOperationException will be thrown in the conditional test.
http://msdn.microsoft.com/en-us/library/bb384091.aspx
Some of the answers to my question Why are there no lifted short-circuiting operators on `bool?`? touch on these aspects too
回答5:
Technically it doesn't work because Nullable<T>
does not define a conversion operator to bool
.
Practically it is not supported for a variety of reasons, including:
- There are no implicit conversions to bool anywhere in C# -- why should there be in
Nullable<T>
?
- Any conversion available would have to be declared for every
T
in Nullable<T>
-- how is that possible when you can plug in your own type as T
that the compiler knows nothing about?
- What would be the semantics of
if(!x)
?
回答6:
It's the most obvious usage for Nullable
Be careful with statements like that. What seem obvious to you isn't necessarily what is obvious for some one else.
Furthermore,
if(x) {}
would also be illegal in case x was a reference type, so in the interest of consistency, the behavior should be the same for Nullables.
回答7:
Anything between the parentheses from the if-statement must evaluate to true or false. A nullable bool can evaluate to null, true or false.
回答8:
You can't do
if (x)
{...}
for the exact same reason you cannot write
int? a = null;
var b = a + 1;
A nullable boolean is not a boolean. In some cases, you want to consider a null bool? as true, and sometimes you want to consider it false. The language design does not make that decision for you.
回答9:
Consider what whould happen in this case then
bool? nullBool = null;
if (nullBool)
{
someCode();
}
It would be impossible to tell if it entered the if senctence because the bool was null or false. That is probably not desirable
回答10:
It's because a nullable bool cannot be implicitly converted to a bool. It's the same reason why you can do this :
int x1 = 7;
int? x2 = x1;
but you can't do this :
int? x1 = 7;
int x2 = x1;
you have to check before if it contains a value. Implicitly converting with nullable types can only be done when assigning a value, not when using that value.