开发者

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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜