2013-08-06 68 views
9

如果你有:泛型和挑戰上解析器前

F(G<A,B>(4)); 

意思用戶想要調用一個方法F與從比較G和A,以及B和常數4導致2個參數?

還是這意味着調用泛型方法G的結果使用類型參數A和B和參數爲4?

+3

第二個!,內部的G (4)會先處理然後F()的調用會執行 –

+0

第二個當然是 –

+0

爲什麼你認爲它是第二個? –

回答

7

所以我試了一下,只是爲了確定。事實證明,這只是正常工作:

void F(int x) { } 
int G<T, U>(int x) { return x; } 

class A { } 
class B { } 

void Main() 
{ 
    F(G<A,B>(4)); 
} 

但是,這產生了一些編譯錯誤:

void F(bool x, bool y) { } 

void Main() 
{ 
    int G = 0, A = 1, B = 2; 
    F(G<A,B>(4)); 
} 

The type or namespace name 'A' could not be found (press F4 to add a using directive or assembly reference)

The type or namespace name 'B' could not be found (are you missing a using directive or an assembly reference?)

The variable 'G' is not a generic method. If you intended an expression list, use parentheses around the < expression.

所以答案是表達F(G<A,B>(4))被解釋爲一個通用函數調用。有許多方法可以強制編譯器將其視爲兩個參數的單個函數調用:F(G<A,B>4)F((G)<A,B>(4))F(G>A,B>(4)),僅舉幾例。

6

您應該閱讀C#規範的7.6.4.2,該規範處理語法歧義並幾乎逐字討論此示例。引述:

If a sequence of tokens can be parsed (in context) as a simple-name (§7.6.2), member-access (§7.6.4), or pointer-member-access (§18.5.2) ending with a type-argument-list (§4.4.1), the token immediately following the closing > token is examined. If it is one of

() ] } : ; , . ? == != |^

then the type-argument-list is retained as part of the simple-name, member-access or pointer-member-access and any other possible parse of the sequence of tokens is discarded.

這裏,G是一個簡單的名稱,問題是<A,B>是否被解釋爲一種類型的參數列表,因爲這簡單的名稱的一部分。

>之後有(,所以片段G<A,B>是方法的簡單名稱。該方法是類型參數爲AB且參數爲4. F因此是具有單個參數的方法的泛型方法。

需要注意的一件有趣的事情是,如果解析失敗,編譯器不考慮任何替代方法。正如你可以從p.s.w.g.的答案中看到的那樣,即使唯一有效的解釋是F是一個需要兩個參數的方法,它也不會被考慮。