2016-05-17 62 views
22

我剛剛從VS 2010升級到2015.我喜歡新的null-conditional operator,這也被稱爲無效傳播。這使得能夠簡化你的代碼,例如:空條件運算符評估bool不bool?如預期

string firstCustomerName = customers?[0].Name; // null if customers or the first customer is null 

另一個問題:

int? count = customers?[0]?.Orders?.Count(); // null if customers, the first customer, or Orders is null 

它返回一個Nullable<int>即使Enumerable.Count返回一個int一個有效的計數和之前的任何nulls區分。這非常直觀,非常有用。

但爲什麼這個編譯工作如預期(它返回false):

string text = null; 
bool contains = text?.IndexOf("Foo", StringComparison.CurrentCultureIgnoreCase) >= 0; 

它要麼返回bool?(它沒有),或無法進行編譯。

+5

哎呦,我想我已經得到了我自己,你可以重寫它:'int? indexof = text?.IndexOf(「Foo」,StringComparison.CurrentCultureIgnoreCase); bool contains = indexof> = 0;' –

+4

我會爲'?> ='運算符投票。:) –

+0

@DStanley:所以包括其他[運營商類別](https://msdn.microsoft.com/en-us/library/aa691323(v = vs.71).aspx)比主?會做更多的傷害,而不是好的。 –

回答

28

你確實有什麼是

string text = null; 
int? index = text?.IndexOf("Foo", StringComparison.CurrentCultureIgnoreCase); 
bool contains = index >= 0; 

int? >= int是完全合法的。

它被拆分的原因有the documentation for the operator狀態「如果條件成員訪問和索引操作鏈中的一個操作返回null,則鏈的其餘部分停止執行,其他操作的優先級較低。 「這意味着.?只會在「創建值」之前評估具有相同優先級或更高優先級的內容。

如果你看一下the order of operator precedence,你會看到「關係和類型測試操作符」在列表中低得多,所以在應用>=之前會創建該值。


UPDATE:因爲它在評論長大,這裏是一個空值打交道時的>=等運營商如何表現的C#5規格部分。我無法找到C#文檔6.

7.3.7擡升運營

擡升運營許可證預定義並且也可以與可爲空的使用的非空值類型操作的用戶定義運算 這些類型的形式。擡起運營商從滿足某些要求的預定義 和用戶定義的操作符構成,如下面的描述 :

  • 對於一元運算符
    + ++ - -- ! ~

    存在如果操作者的提升形式操作數和結果類型都是不可爲空的值類型。解除表格是 構建的,通過添加單個?修飾符的操作數和結果 類型。如果操作數爲 null,提升的運算符會生成一個空值。否則,被解除的操作符展開操作數,應用底層操作符幷包裝結果。

  • 對於二元運算
    + - */% & |^<< >>

    操作者的提升形式存在如果操作數和結果類型 均爲非空值類型。解除表格由 構建,添加單個?修飾符到每個操作數和結果類型。如果一個或兩個操作數都爲空( 例外,即12bool?類型的&和|操作符,如第7.11.3節中的 所述),則提升的 運算符會生成空值。否則,解除操作員解開操作數, 應用底層操作員,幷包裝結果。

  • 對於相等運算
    == !=

    操作者的提升形式如果操作數的類型是既 非空值類型,並且如果結果類型是布爾存在。解除表格 是通過添加單個?修飾符到每個操作數 類型。解除運算符認爲兩個空值相等,並且空值不等於任何非空值。如果兩個操作數都非空,則 解除操作員解開操作數並應用底層 運算符生成布爾結果。

  • 對於關係運算符
    < > <= >=

    操作者的提升形式存在如果操作數類型都是非空值類型,並且如果結果類型是布爾。解除表格 是通過添加單個?修飾符到每個操作數 類型。如果一個或兩個 操作數爲空,則提升的運算符會生成值false。否則,解除操作員解開操作數 並應用底層操作符來​​生成布爾結果。

+0

對於我們這些對C#沒有多少了解的人,當'Nullable'實際上爲null時,運算符'> ='的行爲是什麼? – njzk2

+0

@ njzk2用簡單的術語來說,如果'> ='的任何一邊或兩邊都爲空,它將總是返回false。查看我的更新瞭解完整規範。 –

+0

謝謝@ScottChamberlain – njzk2

3

如果您使用此代碼,將鼠標懸停在x,你看到xint?

var x = text?.IndexOf("Foo", StringComparison.CurrentCultureIgnoreCase); 
bool contains = x >= 0; 

所以打字仍然是正確的。

然後讓我們看看x >= 0:這是一個int? >= int。顯而易見,在可空和不可空的結構之間存在一個操作符。這就是它工作的原因。

如果你看看IL,你會發現它實際上叫做HasValueGetValueOrDefault()。我想有一個運營商這樣做,但我找不到它的參考源,所以它應該是在CLR或編譯器:

instance !0 valuetype [mscorlib]System.Nullable`1<int32>::GetValueOrDefault() 

... 
instance bool valuetype [mscorlib]System.Nullable`1<int32>::get_HasValue() 
+1

確實如此,但可能是空條件運算符會包含'> ='運算符,它會返回一個'bool?'。但我想這是與[_「在表達式繼續_ _中具有較低優先級的其他操作」(https://msdn.microsoft.com/en-us/library/dn986595.aspx)。 –

相關問題