2011-06-21 12 views
6

Estaba pensando en esto. las clases son obviamente pasadas por ptr. Sospecho que las estructuras se transmiten copiándolo, pero no estoy seguro. (Parece un desperdicio para una matriz int tener cada elemento como un ptr. y pasar ptrs para los enteros)¿Cómo implementan los structs los genéricos?

Pero al pensarlo, List<MyStruct> no puedo saber el tamaño de mi estructura. ¿Qué pasa cuando hago esto? ¿Hay varias copias de "List`1" y cada vez que lo uso con un tamaño de almacenamiento no tiene una nueva implementación? (ajustando para las nuevas compensaciones de T y tal).

Eso podría tener sentido ya que la fuente estaría en el CIL dentro de una DLL. Pero estoy adivinando por completo, ¿cómo se hace? ¿Quizás una referencia o número de página a los estándares de ECMA?

+0

Sé poco sobre cómo C# implementa los genéricos. Pero a modo de referencia, así es exactamente cómo funcionan las plantillas C++ (en teoría, se instanciaría una implementación separada de 'List' para cada tipo). –

+0

@Oli: sí, también sé que no compila métodos a menos que lo use y necesita la plantilla en el encabezado. C# no tiene encabezados, pero los genéricos aún funcionan después de haber sido compilados en un dll –

+1

@Oli: Es decir, tendrá implementaciones separadas para cada tipo de valor y una implementación compartida para los tipos de referencia. –

Respuesta

9

genéricos utilizan el concepto de tipos genéricos abiertos y cerrados: una definición de clase genérica parametrizada (es decir, List<T>) es un tipo genérico abierto cuyo tiempo de ejecución genera un tipo genérico cerrado para cada uso diferente que tenga en el código. se crea un tipo diferente para List<int> y List<MyStruct> - para cada tipo genérico cerrado se conoce el tamaño y el tipo de T en tiempo de ejecución.

Aclaración de MSDN:

Cuando un tipo genérico o método es compilado en Microsoft intermedio idioma (MSIL), que contiene metadatos que lo identifica como teniendo tipo parámetros. La forma en que se usa MSIL para un tipo genérico depende de si el tipo de parámetro proporcionado es un tipo de valor o tipo de referencia.

Cuando un tipo genérico es primero construido con un tipo de valor como un parámetro , el tiempo de ejecución crea un tipo genérico especializado con el parámetro suministrado o parámetros sustituido en los ubicaciones apropiadas en el MSIL. Los tipos genéricos especializados se crean una vez para cada tipo de valor único que se usa como como parámetro.

Los genéricos funcionan de forma algo diferente para los tipos de referencia . La primera vez que se construye un tipo genérico con cualquier tipo de referencia , el tiempo de ejecución crea un tipo genérico especializado con referencias de objeto sustituidas por los parámetros en MSIL. Entonces, cada vez que un tipo construido es instancia con un tipo de referencia como su parámetro, independientemente de qué tipo es, el tiempo de ejecución vuelve a utilizar el creado previamente versión especializada del tipo genérico. Esto es posible porque todas las referencias son del mismo tamaño .

2

El CLR compila 1 versión de la clase genérica y la utiliza para todos los tipos de referencia. También compila 1 versión para cada uso de tipo de valor para optimizar el rendimiento.

Cuestiones relacionadas