Cuando tenemos algo como esto:Cómo crear un tipo genérico construido sin especificar ningún tipo de parámetros
interface ISomething<U,V> { ... }
class Something<U,V> : ISomething<U,V> { ... }
typeof(ISomething<,>)
y typeof(Something<,>)
se traducirá en una "definición de tipo genérico". Pero si llegamos al tipo de interfaz como la interfaz implementada por la clase, que será un tipo construido, que ninguno de sus parámetros de tipo son en realidad obligado:
typeof(Something<,>).GetInterfaces().SingleOrDefault()
MSDN menciona específicamente. Lo que quiero es construir el mismo tipo (tipo construido) de ISomething<,>
directamente (sin subclasificarlos y buscar el tipo de base), y no pude encontrar ninguna manera de hacerlo.
Otros detalles:
Incluso he intentado esto:
Type t1 = typeof(ISomething<,>);
Type t2 = t1.MakeGenericType(t1.GetGenericArguments()) // Yields a generic type definition
Type t3 = typeof(Something<,>).GetInterfaces().SingleOrDefault();
En el código anterior:
t1.Equals(t2)
es cierto, pero t1.Equals(t3)
es falso, obviamente porque t3
se construye.
Sorprendentemente, t1.GetGenericArguments()[0].Equals(t3.GetGenericArguments()[0])
es falso, aunque ambos están abiertos (IsGenericParameter = true), y no pude encontrar ninguna diferencia en sus propiedades.
Y esta es la razón por la que necesito hacer esto: Necesito una forma canónica de almacenar objetos de tipo en una lista. Los objetos a veces provienen de clases/interfaces base (como t3 arriba) y algunas veces directamente (como t1). Tendré que ser capaz de compararlos entre sí. No puedo almacenar la definición de tipo genérico (usando .GetGenericTypeDefinition()
) porque a veces tendré un tipo genérico parcialmente abierto (como ISomething) y GetGenericTypeDefinition me dará un tipo sin ningún tipo de argumento especificado.
La única manera de hacer que los tipos sean canónicos que pensé que podrían funcionar, es comprobar si todos los argumentos de tipo están libres, y hacer una GetGenericTypeDefinition. De lo contrario, mantenga el tipo construido.
No creo que esto funciona: "comprobar si todos los argumentos son de tipo no unido y haz una GetGenericTypeDefinition. De lo contrario, conserva el tipo construido ". Supongamos que el tipo que tiene es 'I '. Todos los argumentos de tipo son parámetros de tipo independiente, pero ese es un tipo diferente que 'I '. –
Re: "Sorprendentemente ..." - esto no es sorprendente en absoluto. Sospecho que parte de la confusión de todo esto es que tienes dos tipos completamente diferentes llamados "U" y dos tipos completamente diferentes llamados "V". Por supuesto 'I <,>' es diferente de 'I ' en la lista de interfaz implementada; el primero se parametriza con el '' declarado por 'I', y el otro se parametriza con' 'declarado por' Something'. El hecho de que los parámetros de tipo tengan los mismos nombres no los convierte en el mismo tipo. –
Si tengo un 'I ' construido, y lo llamo GetGenericTypeDefinition(), ¿me dará 'typeof (I )'? – Iravanchi