2012-07-13 26 views
7

我寫的IL靜態分析工具,我有一個很難理解如何管理泛型類型參數引用的規則:IL泛型 - 什麼時候存在什麼規則!T被使用vs!0?

藉此IL(從IList<T> interface):

.property instance !T Item(
    int32 index 
) 
{ 
    .get instance !0 System.Collections.Generic.IList`1::get_Item(int32) 
    .set instance void System.Collections.Generic.IList`1::set_Item(int32, !0) 
} 

爲什麼!0代替!T?我認爲它們與虛擬機的功能是等價的,只要保證名稱的存在,使用位置引用就顯得很奇怪。

更新:額外的情況下,從KeyedCollection.ctor:

IL_0037: newobj instance void class System.Collections.Generic.Dictionary`2<!TKey,!TItem>::'.ctor'(class System.Collections.Generic.IEqualityComparer`1<!0>) 
IL_003c: stfld class System.Collections.Generic.Dictionary`2<!0,!1> class System.Collections.ObjectModel.KeyedCollection`2<!0,!1>::dictionary 
+0

我看不到這個。你確定它不僅僅是你的反彙編程序中的一個bug嗎? – 2012-07-13 20:36:41

+0

嗯,這絕對是反彙編器(在這種情況下monodis)正在產生的東西。 Mono.Cecil(它看起來更像書中的元數據),例如:stfld System.Collections.Generic.Dictionary'2 System.Collections.ObjectModel.KeyedCollection'2 :: dictionary – toshok 2012-07-13 22:41:07

+0

@HansPassant你用什麼來向你展示IL? – casperOne 2012-07-14 01:41:05

回答

4

Common Language Infrastructure standardPartition II - Metadata and File Format,7.1節 「類型」,它規定:

Type ::=  Description 
--------  ----------- 
'!'    Generic parameter in a type definition, accessed by index from 0 

所以答案很簡單:因爲它在規範中。

長答案:這是我的猜測,但基本上,大多數IL命令是基於堆棧的,並始終使用位置參考作爲參數。也就是說,爲了維護IL中的常見模式/使用機制,位置引用被用於泛型是有意義的。

+0

那麼什麼時候使用'!T'? – svick 2012-07-13 19:06:36

+0

@svick不是,它只用於聲明。在元數據中使用名稱的意義在於保留類型參數的名稱,但是在哪裏使用*,它是按位置訪問的。 – casperOne 2012-07-13 19:10:09

+0

這仍然很混亂。 !T在屬性聲明中使用,但它指的是!0所使用的相同通用參數。我應該認爲它們完全可以互換嗎? – toshok 2012-07-13 19:34:33

相關問題