2016-11-18 121 views
6

Roslyn Pattern Matching spec它指出:模式匹配變量範圍

的圖案可變的範圍如下:

如果圖案出現在一個if語句的條件下,它的範圍 是if語句的條件和受控語句,但不包含其他語句。

但是微軟最新的「最新消息」 postspresentations都出現了這個例子:

public void PrintStars(object o) 
{ 
    if (o is null) return;  // constant pattern "null" 
    if (!(o is int i)) return; // type pattern "int i" 
    WriteLine(new string('*', i)); 
} 

足見模式匹配外的模式匹配的,如果水平範圍使用i變量。

這是一個疏忽,還是已經從規範改變範圍?

+0

這將是if語句的_controlled語句_ – juharr

+0

@juharr,那麼受控語句只會返回嗎? –

+0

是的,我錯過了。實際上,我認爲這可能是指更高範圍的「i」,但很難說,因爲它是測試版功能的代碼片段。我想你可以預覽並測試它。 – juharr

回答

3

我張貼a similar question的羅斯林的問題,並通過DavidArno給出了答案:

它的長,但你可以閱讀的爲什麼語言 設計團隊選擇了「加強」的複雜細節這種語言在#12939

TL; DR你並不孤單,認爲改變不直觀, 矛盾的範圍以前的工作方式。團隊可悲的 不在乎,但變化是留在這裏。

似乎作出決定,這個範圍界定將適用,因此該規範已經過時了,這作用域是可悲的是在這裏留下來:

方案3:表達式變量由作用域塊,,的foreach和 using語句,以及所有嵌入式聲明:

什麼是這裏的嵌入語句的意思,是一個被用作另一語句 嵌套聲明 - 除了塊內。因此 if語句的分支,while,foreach等 都將被視爲嵌入。

其後果是,變量總是會逃避 的條件,如果,但從來沒有它的分支。就好像你在所有「你應該」的地方放置了所有的 。

結論

雖然有點微妙,我們將通過選項3.擊中了良好的平衡 :

它使關鍵場景,包括了瓦爾非試方法,如 以及模式並在保鏢if語句中列出變數。它不會導致異常和反直覺的多層次「溢出」。它意味着你將會得到比目前的限制性制度更多的變量。這似乎並不危險,因爲明確的 賦值分析將阻止未初始化的使用。但是, 會阻止重複使用變量名稱,並導致在完成列表中顯示更多名稱 。這似乎是一個合理的折衷。

2

從同一個文檔:

由圖案引入的變量 - 類似於前面所以其實這個代碼描述

了出來變量:

if (!(o is int i)) return; // type pattern "int i" 

更或更少等於:

int i; 
if (!(SomeParsingOn(o, out i))) return; // type pattern "int i" 

這意味着iif的聲明級別相同,這意味着它不僅適用於if的範圍,還適用於以下聲明。這是真實的,可當你複製if作用似乎是:

if (!(o is int i)) return; // type pattern "int i" 
if (!(o is int i)) return; // type pattern "int i" 

給出錯誤CS0128:命名爲「我」在此範圍已經定義的局部變量。

+0

感謝您使用預覽檢查代碼!這似乎與規範文檔相矛盾,我會在github中搜索任何提及的變化。就我個人而言,我不喜歡這個範圍,因爲它與大多數定義變量的語法(catch和using)不匹配。 –

+1

嗯,是的,你是對的。這很尷尬。我希望他們能解決它。也許這只是一個錯誤,或許正在進行中。 –