重写以下代码是否安全:
bool b = foo.bar.HasValue ? foo.bar.Value : false;
到
bool b = foo.bar.Value ?? false;
其中
bar
是可空类型 bool?
最简单的修复方法是
bool b = foo.bar.GetValueOrDefault();
实际上也比
.Value
便宜,因为它省略了有值检查。它将默认为 default(T)
,这里确实是 false
(它只返回底层 T
字段的值,根本没有任何检查)。
如果您需要与
default(T)
不同的默认值,则:
var value = yourNullable.GetValueOrDefault(yourPreferredValue);
你想要的是:
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
始终返回值类型(或者在没有值时抛出异常)。
线路:
bool b = foo.bar.Value ?? false;
如果 foo.bar 没有值,将抛出 InvalidOperationException。
改为使用
var b = foo.bar ?? false;
- 我刚刚从其他答案中了解到.GetValueOrDefault();
- 这看起来是一个非常好的使用建议!
- @ProgrammingHero 的答案也是正确的(添加了 +1!) - 行:
bool b = foo.bar.Value ?? false
实际上无法编译 - 因为
Error 50 Operator '??' cannot be applied to operands of type 'bool' and 'bool'
ffoo.bar ?? false
使用起来会更安全
有编译错误,因为 ?? 的左操作数运算符应该是引用类型或可为空类型。
文章 - 这是一个优雅的 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(...)
相同。。