¿Hay alguna manera de decir, mediante reflexión, que una lista genérica de tipo A está relacionada con una lista genérica de tipo B? Por ejemplo, tengo un List<string>
y un List<int>
. ¿Cómo puedo saber a través de la reflexión que ambos tipos son 'instancias' de List<T>
. Creo que tengo un problema porque List<T>
no es un tipo real. No puede hacer typeof(List<T>)
por ejemplo. List<T>
es un truco de compilación, supongo. Entonces, ¿hay alguna forma de determinar si dos tipos diferentes provienen del List<T>
?Relación entre instancias de la lista <T>
Respuesta
Claro que puedes ... List<>
es en realidad lo que se llama una "tipo genérico no vinculado", lo que significa que no se ha parametrizado con un tipo. Cuando se especifica el argumento tipo, se denomina "tipo genérico enlazado". Un tipo que involucra parámetros de tipo "en bruto", como List<T>
es un "tipo genérico abierto" y uno que solo involucra tipos reales, como List<int>
es un "tipo genérico cerrado". La única situación en la que se puede usar un tipo genérico no vinculado en C# está en el operador typeof. Para acceder al tipo sin consolidar o un tipo cerrado que haría: GetGenericTypeDefinition
Type listOfT = typeof(List<>); // unbound type
Type listOfString = typeof(List<string>); // closed bound type
Type listOfInt32 = typeof(List<int>); // closed bound type
Assert.IsTrue(listOfString.IsGenericType);
Assert.AreEqual(typeof(string), listOfString.GetGenericTypeParameters()[0]);
Assert.AreEqual(typeof(List<>), listOfString.GetGenericTypeDefinition());
Type setOfString = typeof(HashSet<string>);
Assert.AreNotEqual(typeof(List<>), setOfString.GetGenericTypeDefinition());
Ah Ok. Ya veo. Eso parece estar funcionando. Sin embargo, un problema que tengo es que el nombre del objeto Type que vuelve de List <> es 'System.RuntimeType'. Si hago lo mismo para HashSet
Sí, ambos son RuntimeType de la misma forma que "hello" .GetType() y 123.GetType() son ambos System.Type, pero representan dos tipos diferentes. Puede examinar la propiedad FullName si lo desea, pero si está tratando de probar si un tipo particular es listOfT, entonces debe comparar la igualdad como se muestra arriba. – Josh
FullName también devuelve simplemente 'System.RuntimeType'. Como no puedo obtener ningún nombre único de los tipos que vuelven de System.GetGenericTypeDefinition(), no puedo insistir en el hecho de que el tipo procede de una lista
En realidad List<T>
es un tipo real en muchos aspectos (se puede utilizar typeof(List<>)
, por ejemplo), y List<T>
es no simplemente un truco compilador, pero un truco tiempo de ejecución. Pero se puede de hecho comprobar el tipo genérico abierto, a través de algo como:
static Type GetRawType(Type type)
{
return type.IsGenericType ? type.GetGenericTypeDefinition() : type;
}
static void Main()
{
List<int> list1 = new List<int>();
List<string> list2 = new List<string>();
Type type1 = GetRawType(list1.GetType()),
type2 = GetRawType(list2.GetType());
Console.WriteLine(type1 == type2); // true
}
GetGenericTypeDefinition() siempre devuelve un tipo de System.RuntimeType. Eso no es exactamente lo que estoy buscando. Esperaba recuperar 'System.List
Tal vez debería volver a formular la pregunta. ¿Cómo puedo saber si un tipo determinado proviene de la lista
@Bowser, GetGenericTypeDefinition() es lo que desea. bool isListOfT = type.IsGenericType && (type.GetGenericTypeDefinition() == typeof (List <>)); – Josh
Probar:
typeof(List<string>).GetGenericTypeDefinition() == typeof(List<int>).GetGenericTypeDefinition()
(ver http://msdn.microsoft.com/en-us/library/system.type.getgenerictypedefinition.aspx)
Llamar:
List<string> l1 = new List<string>();
List<int> l2 = new List<int>();
Type t1 = l1.GetType().GetGenericTypeDefinition();
Type t2 = l2.GetType().GetGenericTypeDefinition();
Console.Write(t1 == t2);//output: true;
- 1. Relación entre la clase System.Object y Structs
- 2. Diferencia entre la lista <T> y la lista <object>?
- 3. ¿cuál es la diferencia entre la lista <> y el diccionario <> en C#
- 4. Django agregación entre la relación inversa
- 5. relación entre el flop y la metaestabilidad
- 6. Cómo eliminar la relación entre dos entidades
- 7. Diferencia entre la lista <T> y LinkedList <T>
- 8. ¿Cuál es la relación entre ContentPane y JPanel?
- 9. Crear lista de instancias de diferentes objetos
- 10. línea de instancias de una lista constante
- 11. Lista <Object> vs Lista <dynamic>
- 12. Relación entre GEF y GMF?
- 13. Relación entre AppDelegate y main.m
- 14. Relación entre C y C++
- 15. relación entre log4j y apache.commons.logging
- 16. Relación entre HttpContext.Request.Cookies y HttpContext.Response.Cookies
- 17. La comprensión de la relación entre glutDisplayFunc y glutPostRedisplay
- 18. Lista <? extiende MyType>
- 19. Genéricos: Lista <? extiende Animal> es igual que la Lista <Animal>?
- 20. Drupal: Vistas: relación de agrupamiento en la lista de bloqueo
- 21. RequestDispatcher reenviar entre instancias de Tomcat
- 22. Conversión de la lista <Integer> a la lista <String>
- 23. Convertir la lista <MyObject> al Diccionario <obj.string, Lista <obj.ID>>
- 24. Cómo lanzar ArrayList <> de la lista <>
- 25. Perforación _total vs <Todas las instancias>
- 26. Ordenar una lista de instancias de clase Python
- 27. Diferencia entre dos instancias de la misma clase
- 28. La elección entre instancias de plantilla con argumentos puntero
- 29. ¿Cómo hacer comparación de valores entre dos Dictionary <string, lista <string>> objetos
- 30. Lista <int> tarda mucho tiempo en crear instancias con Nhibernate Criteria
Usted debe leer acerca de los genéricos antes de escribir código como eso. – alga
@alga ¿Qué hay de malo con el código? Están intentando aprender más sobre los genéricos y han formulado una pregunta fantástica de la que dudo mucho. Los programadores de .NET conocen la respuesta. – Eilon
Estoy de acuerdo con Eilon. – Josh