Rewrite HasValue to the ?? Operators
Is it safe to rewrite the following code:
bool b = foo.bar.HasValue ? foo.bar.Value : false;
to
bool b = foo.bar.Value ?? false;开发者_运维知识库
where bar
is the nullable type bool?
The easiest fix there is
bool b = foo.bar.GetValueOrDefault();
which is also actually cheaper than .Value
as it omits the has-value check. It will default to default(T)
, which is indeed false
here (it just returns the value of the underlying T
field, without any checks at all).
If you need a different default to default(T)
, then:
var value = yourNullable.GetValueOrDefault(yourPreferredValue);
What you want is:
bool b = foo.bar ?? false;
This is (surprisingly) safe and an intended use for the null-coalescing operator.
The ?? operator is called the null-coalescing operator and is used to define a default value for a nullable value types as well as reference types. It returns the left-hand operand if it is not null; otherwise it returns the right operand.
Source: http://msdn.microsoft.com/en-us/library/ms173224.aspx
In the case of Nullable<T>
, it is functionally equivalent to Nullable<T>.GetValueOrDefault(T defaultValue)
.
The code:
bool b = foo.bar.Value ?? false;
Will cause a compiler-error, because you cannot apply the operator to value types, and Nullable<T>.Value
always returns a value-type (or throws an exception when there is no value).
No - this is not safe.
The line:
bool b = foo.bar.Value ?? false;
will throw an InvalidOperationException if foo.bar has no value.
Instead use
var b = foo.bar ?? false;
Update - I just learned about .GetValueOrDefault();
from the other answers - that looks like a very good suggestion to use!
Update 2 - @ProgrammingHero's answer is also correct (+1 added!) - the line:
bool b = foo.bar.Value ?? false
actually won't compile - because of Error 50 Operator '??' cannot be applied to operands of type 'bool' and 'bool'
Nope.
The Value property returns a value if one is assigned, otherwise a System.InvalidOperationException is thrown.
From: http://msdn.microsoft.com/en-us/library/1t3y8s4s%28v=vs.80%29.aspx
So if hasValue is false then you will get an exception thrown in your second one when you try to run it.
ffoo.bar ?? false
would be more safer to use
bar.Value ?? false
has compilation error, because left operand of ?? operator should be of reference or nullable type.
Maybe you have a look at this article in Stackoverflow too - it is an elegant null checking in the style obj.IfNotNull(lambdaExpression)
- returning the object you want if obj is not null otherwise just null (but without throwing an exception).
I used it with the Entity Framework if you're accessing a referenced entity, e.g.
var str=Entity1.Entity2.IfNotNull(x=>x.EntityDescription) ?? string.Empty
which returns EntityDescription
contained in Entity2
which is referenced by Entity1
- or an empty string if any object Entity1
or Entity2
is null
. Without IfNotNull
you would get a long and ugly expression.
The extension method IfNotNull
is defined there as follows:
public static TOut IfNotNull<TIn, TOut>(this TIn v, Func<TIn, TOut> f)
where TIn : class
where TOut: class
{
if (v == null) return null; else return f(v);
}
Update:
If you update the code to C# version 6.0 (.NET Framework 4.6 - but seems to support older frameworks 4.x too), there is a new operator available which makes this task easy: The "elvis" operator ?.
.
It works as follows:
var str=(Entity1.Entity2?.EntityDescription) ?? string.Empty
In this case, if Entity2
is null
, evaluation stops and (...)
becomes null
- after which the ?? string.empty
part replaces null
by string.Empty
. In other words, it works the same way as .IfNotNull(...)
would.
foo.bar.Value represents the non-nullable value when there is one, and throws an InvalidOperationException if there’s no real value.
精彩评论