我爲什麼不能叫SomeGenericMethod<SomeGenericType<>>
最簡單的回答是:因爲language specification是這麼說的:
4.4構造類型
泛型類型聲明,本身就表示一種未綁定的泛型,它被用作「藍圖」來形成許多不同的類型應用類型參數。類型參數寫在通用類型名稱後面的尖括號(<和>)中。包含至少一個類型參數的類型稱爲構造類型。構造類型可用於大多數語言中可以顯示類型名稱的地方。 未綁定的泛型類型只能在typeof-表達式(§7.6.11)中使用。
4.4.3結合和未結合類型
術語未綁定類型是指一種非通用型或未結合的通用類型。術語綁定類型是指非泛型類型或構造類型。 未綁定類型是指由類型聲明聲明的實體。未綁定的泛型類型本身不是一個類型,不能用作變量的類型,參數或返回值,或者作爲基類型。 唯一可以引用非綁定泛型類型的構造是typeof表達式(第7.6.11節)。
爲什麼C#規範是這麼說的?因爲CLI spec決定了還有:
II.9.4實例化泛型類型
...
CLI不支持泛型類型的實例部分。泛型類型不得在元數據簽名blob中的任何地方顯示爲無實例。
好的,現在讓我們停止使用法律術語。實際的回答你的問題是:
當你調用SomeMethod<SomeType>()
首次,CLR會調用JIT編譯器,它會讀取SomeMethod<T>
,替代T
,並且創建代表SomeMethod<SomeType>
新的可執行代碼。
當您撥打SomeMethod<SomeOtherType>()
時,需要重複該過程,將爲SomeMethod<SomeOtherType>
生成全新的代碼。
您不能只爲非結合泛型類型(如Generic<>
)創建有效代碼。在一般情況下,JIT無法知道在不知道T
的情況下生成什麼代碼表示。
- 如果
T
是string
和您的方法聲明T
類型的局部變量,所述JIT將分配堆棧空間或使用寄存器與天然指針的大小。
- 如果
T
是Guid
,JIT將不得不爲固定的128位值分配堆棧空間。如果它不知道T
將會是什麼,它就不能生成代碼。
因此,一般,您無法生成未綁定類型的可執行代碼。爲什麼你可以說可能對你提供的代碼段做了這樣的事情,這將需要特殊的外殼,並且如果你在PrintType
方法中添加了T
本地代碼,你的調用代碼將停止工作。由於泛型必須在組件之間可重用,因此調用代碼不能假定被調用方法的任何內容。
基本上'typeof'可以採用通用類名稱,它沒有定義通用類型,但是如果將類型作爲通用類型傳遞,它必須是一個完全定義的類型,而'Generic <>'不是。 – juharr
@juharr像往常一樣在這裏,迄今爲止最好的答案是在評論中。所以可以肯定地說,這是不可能的**。 – talles
我認爲rbaghbanli在說同樣的事情。但是,不能將'Generic <>'作爲泛型類型傳遞。注意如果你使用'typeof(Generic