2012-07-13 11 views
7

estoy escribiendo una herramienta de análisis estático IL, y estoy teniendo dificultades para comprender las reglas que gobiernan cómo se hace referencia a los parámetros de tipo genérico:genéricos de IL: ¿qué reglas existen para cuándo! T se usa vs! 0?

aprovechar esta IL (del 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) 
} 

¿Por qué la !0 allí en vez de !T? Supongo que son equivalentes en lo que respecta a la máquina virtual, parece extraño usar referencias posicionales cuando se tiene la garantía de tener los nombres.

Actualización: un caso adicional, desde 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

no veo esto. ¿Estás seguro de que no es solo un error en tu desensamblador? –

+0

Hm, es definitivamente algo que está generando el desensamblador (en este caso monodis). Mono.Cecil (que parece ser mucho más acorde con los metadatos de los libros) muestra, por ejemplo: stfld System.Collections.Generic.Dictionary'2 System.Collections.ObjectModel.KeyedCollection'2 :: dictionary – toshok

+0

@HansPassant ¿Qué estás usando para mostrarte el IL? – casperOne

Respuesta

4

En los "tipos" Common Language Infrastructure standard, Partition II - Metadata and File Format, la cláusula 7.1 se afirma:

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

respuesta tan corto: porque está en la especificación.

Respuesta larga: Esta es la especulación de mi parte, pero en el fondo, la mayoría de los comandos de IL-se basa apilar y utilizar referencias posicionales como parámetros todo el tiempo. Dicho esto, tiene sentido que las referencias posicionales se usen para genéricos, a fin de mantener patrones/mecanismos de uso comunes en IL.

+0

Entonces, ¿cuándo se usa '! T'? – svick

+0

@svick No lo es, solo se usa para declaración. El objetivo de tener el nombre en los metadatos es preservar el nombre del parámetro tipo, pero cuando se usa *, se accede por posición. – casperOne

+0

eso todavía es bastante confuso. ! T se usa en la declaración de la propiedad, pero se refiere al mismo parámetro genérico que! 0 hace. ¿Debería asumir que son totalmente intercambiables? – toshok