关于c#:将HasValue重写为??

Rewrite HasValue to the ?? Operators

重写以下代码是否安全:

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

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

其中bar为可空类型bool?


最简单的解决方法是

1
bool b = foo.bar.GetValueOrDefault();

这实际上也比.Value便宜,因为它省略了has值检查。它将默认为default(T),这里实际上是false(它只返回基础T字段的值,而不进行任何检查)。

如果您需要对default(T)使用不同的默认值,那么:

1
var value = yourNullable.GetValueOrDefault(yourPreferredValue);


你想要的是:

1
bool b = foo.bar ?? false;

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

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.

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

Nullable的情况下,它在功能上等同于Nullable.GetValueOrDefault(T defaultValue)

代码:

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

将导致编译器错误,因为不能将运算符应用于值类型,并且Nullable.Value始终返回值类型(或在没有值时引发异常)。


不-这不安全。

那行:

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

如果foo.bar没有值,将引发InvalidOperationException。

代替使用

1
var b = foo.bar ?? false;

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

更新2-@programmingero的答案也是正确的(+1已添加!)-线:

2

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


1
bar.Value ?? false

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


使用ffoo.bar ?? false会更安全。


不。

0

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

因此,如果hasValue为false,那么当您尝试运行它时,您将在第二个异常中引发异常。


也许您也可以在StackOverflow中看到这篇文章——它是一个优雅的风格obj.IfNotNull(lambdaExpression)中的空检查——如果obj不是空的,则返回您想要的对象,否则只返回空值(但不引发异常)。

如果您要访问引用的实体,例如

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

返回Entity2中包含的EntityDescription,由Entity1引用;如果对象Entity1Entity2null则返回空字符串。没有IfNotNull你会得到一个又长又丑的表情。

扩展方法IfNotNull定义如下:

1
2
3
4
5
6
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-但似乎也支持旧的Framework 4.x),则可以使用一个新的运算符来简化此任务:"elvis"运算符?.

其工作原理如下:

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

在这种情况下,如果Entity2null,则停止评估,(...)变成null,之后,?? string.empty部分由string.Empty代替null。换句话说,它的工作方式与.IfNotNull(...)的工作方式相同。


foo.bar.value表示存在不可为空的值,如果没有实际值,则抛出InvalidOperationException。