将 HasValue 重写为 ??运营商

问题描述 投票:0回答:8

重写以下代码是否安全:

bool b = foo.bar.HasValue ? foo.bar.Value : false;

bool b = foo.bar.Value ?? false;

其中

bar
是可空类型
bool?

c# nullable syntactic-sugar
8个回答
31
投票

最简单的修复方法是

bool b = foo.bar.GetValueOrDefault();

实际上也比

.Value
便宜,因为它省略了有值检查。它将默认为
default(T)
,这里确实是
false
(它只返回底层
T
字段的值,根本没有任何检查)。

如果您需要与

default(T)
不同的默认值,则:

var value = yourNullable.GetValueOrDefault(yourPreferredValue);

18
投票

你想要的是:

bool b = foo.bar ?? false;

这是(令人惊讶的)安全,并且是空合并运算符的预期用途。

的?运算符称为空合并运算符,用于定义“可空值类型”以及引用类型的默认值。如果左侧操作数不为空,则返回;否则它返回正确的操作数。

来源:
http://msdn.microsoft.com/en-us/library/ms173224.aspx

对于

Nullable<T>

,其功能等同于

Nullable<T>.GetValueOrDefault(T defaultValue)
代码:

bool b = foo.bar.Value ?? false;

会导致编译器错误,因为您无法将运算符应用于值类型,并且
Nullable<T>.Value

始终返回值类型(或者在没有值时抛出异常)。

    


8
投票

线路:

bool b = foo.bar.Value ?? false;

如果 foo.bar 没有值,将抛出 InvalidOperationException。

改为使用

var b = foo.bar ?? false;



更新

- 我刚刚从其他答案中了解到.GetValueOrDefault(); - 这看起来是一个非常好的使用建议!



更新 2

- @ProgrammingHero 的答案也是正确的(添加了 +1!) - 行: bool b = foo.bar.Value ?? false

实际上无法编译 - 因为 
Error 50 Operator '??' cannot be applied to operands of type 'bool' and 'bool'

    


2
投票

Value 属性返回一个值,如果 一个被分配,否则一个 System.InvalidOperationException 是 扔了。

来自:
http://msdn.microsoft.com/en-us/library/1t3y8s4s%28v=vs.80%29.aspx

因此,如果 hasValue 为 false,那么当您尝试运行第二个函数时,您将抛出异常。


2
投票
ffoo.bar ?? false

使用起来会更安全

    


2
投票
有编译错误,因为 ?? 的左操作数运算符应该是引用类型或可为空类型。


1
投票
this

文章 - 这是一个优雅的 null 检查风格 obj.IfNotNull(lambdaExpression) - 如果 obj 不为 null,则返回你想要的对象,否则只是 null (但不会抛出异常)。


如果您要访问引用的实体,例如,我将其与实体框架一起使用。

var str=Entity1.Entity2.IfNotNull(x=>x.EntityDescription) ?? string.Empty

返回 
EntityDescription

中包含的

Entity2
,由
Entity1
引用 - 或者如果有任何对象
Entity1
Entity2
null
,则返回空字符串。如果没有
IfNotNull
,你会得到一个又长又难看的表情。
扩展方法

IfNotNull

定义如下:


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); }



更新:

如果您将代码更新到 C# 版本 6.0(.NET Framework 4.6 - 但似乎也支持较旧的框架 4.x),则可以使用一个新的运算符来简化此任务:“elvis”运算符 ?.

.
其工作原理如下:

var str=(Entity1.Entity2?.EntityDescription) ?? string.Empty

在这种情况下,如果 
Entity2

null
,则评估停止并且
(...)
变为
null
- 之后
?? string.empty
部分将
null
替换为
string.Empty
。换句话说,它的工作方式与
.IfNotNull(...)
相同。
    


0
投票
如果没有实际值,则抛出 InvalidOperationException

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.