2016-08-22 24 views
4

在執行成員訪問之前,我已經知道空條件運算符can be used to test爲null。C#6空條件運算符 - 作爲代碼切換器?

例如:

int? length = customers?.Length; // null if customers is null 
Customer first = customers?[0]; 

如果customerscustomers?.Length爲null,則customers?.Length將返回null和null將在int? length = ...可變

我也知道,它可以used單個原子在多線程環境中調用方法:

public void OnFoo() 
{ 
    Foo?.Invoke(this, EventArgs.Empty); 
} 

AFAIU - 如果Foonull然後

Foo?.Invoke(this, EventArgs.Empty); 

同樣是null

所以我們留下了

public void OnFoo() 
{ 
    null; //compilation error 
} 

所以我要問:

問題

似乎空條件運算符不僅用於測試空,如果有,那麼它進行更深層次的:x?.y?.c?.d -

,但它也像代碼切換:

像這樣:

public void OnFoo() 
    { 
     Foo?.Invoke(this, EventArgs.Empty); //Let's assume Foo =null; 
    } 

變爲

public void OnFoo() 
    { 

    } 

對不起,對嗎?我沒有找到這方面的任何文件。

回答

6

空條件運算符是一個操作導致的表達 - 它不是一個聲明

您的關於Foo?.Invoke(this, EventArgs.Empty)等效於null的邏輯並沒有成立,因爲它似乎假設了一種不適用的「模板替換」。

類型表達

​​

的是什麼,因爲Invokevoid返回類型。你不能寫:

// Invalid 
var result = Foo?.Invoke(this, EventArgs.Empty); 

這就像在7.6。的C#5規範的5:

評估一個調用表達式如下被分類的結果是:

  • 如果調用表達式調用一個方法或委託返回void,結果是沒有。只有在語句表達式(§8.6)或lambda表達式(§7.15)的主體中才允許分類爲無表達式的表達式。否則會發生綁定時錯誤。
  • 否則,結果是由方法或委託返回的類型的值。

甲成員調用可以使用一個空條件運算,在該點時的主要表達式計算爲一個非空值時,才執行該調用。涉及空條件運算符的調用表達式的結果與使用常規.運算符時的結果相同,只是如果結果爲非空值類型,則帶有空條件運算符的結果爲相應的可空值類型。

當C#6規範出現時,所有這些都會更精確 - 但我不知道那會是什麼時候。 (我不認爲認爲目前有一個C#6規範,我相信在MS中有一個內部規範,但不是公共規範的一個,因爲標準化C#5越來越接近ECMA標準化過程,這可能會影響C#6的發佈過程。)

+0

感謝Jon。但是:_ [如果您可以打印它,或者將其分配給一個變量,則它是一個表達式。如果你不能,這是一個聲明](https://www.quora.com/Whats-the-difference-between-a-statement-and-an-expression-in-Python)._。因爲我不能通過:var result = Foo?.Invoke(this,EventArgs.Empty);' - 然後根據他的鏈接,它是一個聲明。我的錯誤在哪裏? –

+1

@RoyiNamir:這是關於Python,而不是C#,我懷疑它還是過於簡化。你的'var result = ...;'不會編譯,因爲'Invoke'返回'void' ...我不確定你在問什麼。 –

+0

Jon - [我在做夢](https://github.com/ljw1004/csharpspec/blob/gh-pages/CSharp%20Language%20Specification.pdf?raw=true)?請參閱第188頁 –