usando tipos tipo ser referencia parametros objeto genericos generico genericas generic debe crear clases c# generics

ser - tipos de parametros c#



¿Es imposible usar Generics dinámicamente? (2)

Esta pregunta ya tiene una respuesta aquí:

Necesito crear instancias en tiempo de ejecución de una clase que usa genéricos, como class<T> , sin saber previamente el tipo T que tendrán, me gustaría hacer algo como eso:

public Dictionary<Type, object> GenerateLists(List<Type> types) { Dictionary<Type, object> lists = new Dictionary<Type, object>(); foreach (Type type in types) { lists.Add(type, new List<type>()); /* this new List<type>() doesn''t work */ } return lists; }

... pero no puedo. Creo que no es posible escribir en C # dentro de los corchetes genéricos una variable de tipo. ¿Hay alguna otra forma de hacerlo?


No se puede hacer así, el objetivo de los genéricos es principalmente la seguridad de tipo de tiempo de compilación , pero puedes hacerlo con la reflexión:

public Dictionary<Type, object> GenerateLists(List<Type> types) { Dictionary<Type, object> lists = new Dictionary<Type, object>(); foreach (Type type in types) { Type genericList = typeof(List<>).MakeGenericType(type); lists.Add(type, Activator.CreateInstance(genericList)); } return lists; }


Según la frecuencia con que llame a este método, usar Activator.CreateInstance podría ser lento. Otra opción es hacer algo como esto:

diccionario privado> delegados = nuevo diccionario> ();

public Dictionary<Type, object> GenerateLists(List<Type> types) { Dictionary<Type, object> lists = new Dictionary<Type, object>(); foreach (Type type in types) { if (!delegates.ContainsKey(type)) delegates.Add(type, CreateListDelegate(type)); lists.Add(type, delegates[type]()); } return lists; } private Func<object> CreateListDelegate(Type type) { MethodInfo createListMethod = GetType().GetMethod("CreateList"); MethodInfo genericCreateListMethod = createListMethod.MakeGenericMethod(type); return Delegate.CreateDelegate(typeof(Func<object>), this, genericCreateListMethod) as Func<object>; } public object CreateList<T>() { return new List<T>(); }

En el primer golpe creará un delegado al método genérico que crea la lista y luego la coloca en un diccionario. En cada golpe posterior, simplemente llamará al delegado para ese tipo.

¡Espero que esto ayude!