重写以下代码是否安全:
bool b = foo.bar.HasValue ? foo.bar.Value : false;
到
bool b = foo.bar.Value ?? false;
其中bar
是可空类型bool?
答案 0 :(得分:25)
最容易解决的问题是
bool b = foo.bar.GetValueOrDefault();
实际上也比.Value
便宜,因为它省略了有效值检查。它将默认为default(T)
,这里确实是false
(它只返回基础T
字段的值,而不进行任何检查。
如果您需要与default(T)
不同的默认值,则:
var value = yourNullable.GetValueOrDefault(yourPreferredValue);
答案 1 :(得分:12)
你想要的是:
bool b = foo.bar ?? false;
这是(令人惊讶的)安全性和无效合并运算符的预期用途。
?? operator被称为null-coalescing运算符,用于定义可空值类型的默认值以及引用类型。如果它不为null,则返回左侧操作数;否则它返回正确的操作数。
来源: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
始终返回值类型(或在没有值时抛出异常)。
答案 2 :(得分:7)
不 - 这不安全。
该行:
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'
答案 3 :(得分:2)
不。
Value属性返回值if 一个被分配,否则一个 System.InvalidOperationException是 抛出。
来自:http://msdn.microsoft.com/en-us/library/1t3y8s4s%28v=vs.80%29.aspx
因此,如果hasValue为false,那么当您尝试运行它时,您将在第二个中抛出异常。
答案 4 :(得分:2)
ffoo.bar ?? false
使用
答案 5 :(得分:2)
bar.Value ?? false
有编译错误,因为左操作数?运算符应该是引用或可空类型。
答案 6 :(得分:1)
也许您也可以查看Stackoverflow中的this文章 - 它是样式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 - 但是seems to support older frameworks 4.x too),则可以使用新的运算符来简化此任务:“elvis”运算符 ?.
。
它的工作原理如下:
var str=(Entity1.Entity2?.EntityDescription) ?? string.Empty
在这种情况下,如果Entity2
为null
,则评估停止,(...)
变为null
- 之后?? string.empty
部分将取代null
按string.Empty
。换句话说,它的工作方式与.IfNotNull(...)
的工作方式相同。
答案 7 :(得分:0)
foo.bar.Value表示有一个值时的非可空值,,如果没有实际值则抛出InvalidOperationException 。