uso usando tipos tipo ser requiere referencia instanciar genericos generico genericas debe colecciones clases argumentos c# .net generics

c# - usando - Pase un sistema instanciado. Escriba como un parámetro de tipo para una clase genérica.



tipos de genericos (4)

El título es algo oscuro. Lo que quiero saber es si esto es posible:

string typeName = <read type name from somwhere>; Type myType = Type.GetType(typeName); MyGenericClass<myType> myGenericClass = new MyGenericClass<myType>();

Obviamente, MyGenericClass se describe como:

public class MyGenericClass<T>

En este momento, el compilador se queja de que ''El tipo o el espacio de nombres'' myType ''no se pudo encontrar. "Tiene que haber una manera de hacer esto.


Algunos adicionales sobre cómo correr con el código de tijeras. Supongamos que tiene una clase similar a

public class Encoder() { public void Markdown(IEnumerable<FooContent> contents) { do magic } public void Markdown(IEnumerable<BarContent> contents) { do magic2 } }

Supongamos que en tiempo de ejecución tiene un FooContent

Si pudieras enlazar en tiempo de compilación querrías

var fooContents = new List<FooContent>(fooContent) new Encoder().Markdown(fooContents)

Sin embargo, no puedes hacer esto en tiempo de ejecución. Para hacer esto en tiempo de ejecución, harías lo siguiente:

var listType = typeof(List<>).MakeGenericType(myType); var dynamicList = Activator.CreateInstance(listType); ((IList)dynamicList).Add(fooContent);

Para invocar dinámicamente el contenido de Markdown(IEnumerable<FooContent> contents)

new Encoder().Markdown( (dynamic) dynamicList)

Tenga en cuenta el uso de dynamic en la llamada al método. En tiempo de ejecución, dynamicList será List<FooContent> (además, también será IEnumerable<FooContent> ), ya que el uso uniforme de dynamic aún está enraizado en un lenguaje fuertemente tipado, el corrector de tiempo de ejecución seleccionará el método Markdown adecuado. Si no hay coincidencias de tipos exactos, buscará un método de parámetro de objeto y si ninguno coincide con una excepción de encuadernador de tiempo de ejecución se generará una alerta que no coincide con ningún método.

El obvio inconveniente de este enfoque es una gran pérdida de seguridad de tipo en tiempo de compilación. Sin embargo, el código a lo largo de estas líneas le permitirá operar en un sentido muy dinámico que en el tiempo de ejecución aún está completamente tipeado como espera que sea.


Desafortunadamente no, no hay. Los argumentos genéricos deben poder resolverse en Tiempo de compilación como 1) un tipo válido o 2) otro parámetro genérico. No hay forma de crear instancias genéricas basadas en valores de tiempo de ejecución sin el gran martillo del uso de la reflexión.


Mis requisitos eran ligeramente diferentes, pero espero ayudar a alguien. Necesitaba leer el tipo de una configuración y crear una instancia del tipo genérico de forma dinámica.

namespace GenericTest { public class Item { } } namespace GenericTest { public class GenericClass<T> { } }

Finalmente, así es como lo llamas. Define el tipo con un backtick .

var t = Type.GetType("GenericTest.GenericClass`1[[GenericTest.Item, GenericTest]], GenericTest"); var a = Activator.CreateInstance(t);


No puedes hacer esto sin reflexión. Sin embargo, puedes hacerlo con reflexión. Aquí hay un ejemplo completo:

using System; using System.Reflection; public class Generic<T> { public Generic() { Console.WriteLine("T={0}", typeof(T)); } } class Test { static void Main() { string typeName = "System.String"; Type typeArgument = Type.GetType(typeName); Type genericClass = typeof(Generic<>); // MakeGenericType is badly named Type constructedClass = genericClass.MakeGenericType(typeArgument); object created = Activator.CreateInstance(constructedClass); } }

Nota: si su clase genérica acepta múltiples tipos, debe incluir las comas cuando omite los nombres de tipo, por ejemplo:

Type genericClass = typeof(IReadOnlyDictionary<,>); Type constructedClass = genericClass.MakeGenericType(typeArgument1, typeArgument2);