2012-07-13 9 views
7

Ich bin ein IL statisches Analyse-Tool zu schreiben, und ich habe eine harte Zeit zu verstehen, die Regeln, wie generische Typparameter referenziert aufweisen, sind:IL-Generika - welche Regeln gibt es, wenn! T verwendet wird vs.! 0?

diesen IL nehmen (von den 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) 
} 

Warum ist die !0 dort statt !T? Ich vermute, dass sie gleichwertig sind, was die VM betrifft, es scheint nur seltsam, Positionsreferenzen überhaupt zu verwenden, wenn Sie garantiert die Namen haben.

Update: ein zusätzlicher Fall von 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

Ich sehe das nicht. Sind Sie sicher, dass es sich nicht nur um einen Fehler in Ihrem Disassembler handelt? –

+0

Hm, es ist definitiv etwas, was der Disassembler (in diesem Fall Monodis) erzeugt. Mono.Cecil (das anscheinend viel mehr im Buch Metadaten zeigt) zeigt zB: stfld System.Collections.Generic.Dictionary'2 System.Collections.ObjectModel.KeyedCollection'2 :: dictionary – toshok

+0

@HansPassant Was benutzt du, um dir die IL zu zeigen? – casperOne

Antwort

4

In den Common Language Infrastructure standard, Partition II - Metadata and File Format, Abschnitt 7.1 "Typen" heißt es:

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

So kurze Antwort: weil Es ist in der Spezifikation.

Lange Antwort: Dies ist meinerseits Spekulation, aber im Grunde genommen sind die meisten IL-Befehle stack-basiert und verwenden ständig Positionsreferenzen als Parameter. Dennoch ist es sinnvoll, Positionsbezüge für Generika zu verwenden, um gängige Muster/Anwendungsmechanismen in IL zu erhalten.

+0

Wann wird '! T' verwendet? – svick

+0

@svick Es ist nicht, es wird nur für die Deklaration verwendet. Der Punkt, an dem der Name in den Metadaten steht, besteht darin, den Namen des Typparameters beizubehalten, aber wo er * verwendet wird, wird auf die Position zugegriffen. – casperOne

+0

das ist immer noch ziemlich verwirrend. ! T wird in der Deklaration für die Eigenschaft verwendet, bezieht sich jedoch auf den gleichen generischen Parameter, den! 0 tut. Sollte ich nur annehmen, dass sie völlig austauschbar sind? – toshok