是否安全,改寫下面的代碼:重寫HasValue的??運營商
bool b = foo.bar.HasValue ? foo.bar.Value : false;
到
bool b = foo.bar.Value ?? false;
其中bar
是可空類型bool?
是否安全,改寫下面的代碼:重寫HasValue的??運營商
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.Value ?? false;
將引發InvalidOperationException如果foo.bar沒有價值。
而是使用
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'
'foo.bar'的類型是'bool?',但'foo.bar.Value'只是'bool',這就是您應該使用'??'的原因。運算符僅限於'foo.bar' - 它具有正確的類型。記住'??'用您指定的需要可爲空或引用類型的值替換null,而bool只是一個值類型。 – Matt
都能跟得上。如果 之一被分配
Value屬性返回一個值,否則 System.InvalidOperationException是 拋出。
來源:http://msdn.microsoft.com/en-us/library/1t3y8s4s%28v=vs.80%29.aspx
所以,如果hasValue的是假的,那麼你會得到你的第二個拋出當您嘗試運行異常。
ffoo.bar ?? false
會更安全的使用
你想要的是:
bool b = foo.bar ?? false;
這是(奇怪)安全的空合併運算符的用途。
的??操作者被稱爲空合併運算符和用於定義要空值類型的默認值以及引用類型。如果它不是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
始終返回值類型(或拋出時,有沒有價值除外) 。
foo.bar.Value表示有一個的非空值,,如果沒有實際值則拋出InvalidOperationException。
bar.Value ?? false
有編譯錯誤,因爲左操作的?運算符應該是引用或可爲空類型。
也許你看看Stackoverflow中的this文章 - 這是一個優雅的空檢查風格obj.IfNotNull(lambdaExpression)
- 如果obj不爲null,則返回所需的對象,否則僅爲null(但不會拋出異常)。
如果您正在訪問引用的實體,例如我使用它與實體框架。
var str=Entity1.Entity2.IfNotNull(x=>x.EntityDescription) ?? string.Empty
它返回包含在Entity2
其通過引用Entity1
EntityDescription
- 或空字符串如果任何對象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框架4.6 - 但seems to support older frameworks 4.x too)有一個新的操作員可以使這項任務變得簡單:「elvis」操作員?.
。
其工作原理如下:
var str=(Entity1.Entity2?.EntityDescription) ?? string.Empty
在這種情況下,如果Entity2
是null
,評估停止,(...)
成爲null
- 在?? string.empty
部分由string.Empty
取代null
之後。換句話說,它的工作方式與.IfNotNull(...)
相同。
每天學習新東西。不知道我用了多少次'Nullable'而只是不知道這些方法。 –
shambulator
優秀的答案。 –