variable type multiple method generic delegate clase c# generics

c# - type - Genéricos: tipos construidos abiertos y cerrados



generic variable c# (3)

Desde MSDN :

Un tipo o método genérico se cierra si se han sustituido los tipos de instancia para todos sus parámetros de tipo, incluidos todos los parámetros de tipo de todos los tipos adjuntos. Solo puede crear una instancia de un tipo genérico si está cerrado.

Esto funciona cuando List<int> está cerrado :

var list = Activator.CreateInstance(typeof(List<int>));

Pero esto arroja una excepción en el tiempo de ejecución porque List<> está abierto :

var list = Activator.CreateInstance(typeof(List<>)); ↑

Recientemente noté que los tipos construidos genéricos pueden ser abiertos y cerrados. Pero no entiendo lo que realmente significan. ¿Puedes dar un ejemplo simple?


En la práctica, la terminología en realidad no importa mucho; no recuerdo la última vez que tuve que preocuparme de ella, excepto cuando intentaba escribir sobre ella.

  • Un tipo no vinculado no tiene ningún tipo de argumentos especificados
  • Un tipo construido tiene al menos un tipo de argumento especificado
  • Un parámetro de tipo es un tipo abierto
  • Un tipo de matriz donde el tipo de elemento está abierto es un tipo abierto
  • Un tipo abierto construido tiene al menos un argumento tipo que es un tipo abierto
  • Un tipo cerrado es cualquier tipo que no esté abierto

(Hay otras reglas para los tipos anidados. Consulte la sección de especificaciones de C # 3.0 4.4 para obtener detalles sangrientos).

Como ejemplo de un tipo abierto construido, considere:

public class NameDictionary<T> : Dictionary<string, T>

La clase base de typeof(NameDictionary<>) es:

  • Construido porque especifica argumentos de tipo
  • Abierto porque el segundo argumento de tipo ( T ) es un tipo abierto

Los documentos de MSDN para Type.IsGenericType tienen una tabla bastante útil.

Solo para reiterar, esto es casi completamente sin importancia en el uso diario.

En general, estoy a favor de conocer la terminología correcta, particularmente para cosas como "pasar por referencia", etc., pero en este caso, realmente, no aparece muy a menudo. Me gustaría desanimarlo activamente para que no se preocupe por eso :)


En su mayoría he usado genéricos abiertos (genéricos básicamente desinstalados) en mapeos de inyección de dependencia. Por ejemplo, algo así como

Bind<IRepository<>>() .To<BasicRepository<>>()

Entonces, cuando mi constructor de objetos contiene:

public SomethingController(IRepository<Something>) { ... }

Mi mecanismo de inyección de dependencia instanciará un BasicRepository <Something> automágicamente. (Esto funciona con Ninject y StructureMap, y probablemente con la biblioteca Castle Windsor; no estoy seguro de otros frameworks).