2011-04-08 10 views
18

Supongamos que tenemos una clase anidada genérica:¿.Net soporta genéricos al curry?

public class A<T> { 
    public class B<U> { } 
} 

Aquí, typeof(A<int>.B<>) es en esencia una clase genérica con dos parámetros, donde sólo el primero está obligado.

Si tengo una sola clase con dos parámetros

public class AB<T, U> { } 

¿Hay una manera de referirse a "AB con T=int y U permanecer abierta"? Si no, ¿es esto una limitación de C# o una limitación de CLR?

+1

¿Se puede hacer esto con los tipos en F #? – GregC

+0

Si me preguntas, no tengo ni idea ... nunca he usado F # por un período de tiempo. – configurator

+1

¿Por "al curry", quiere decir "parcialmente cerrado"? – Gabe

Respuesta

10

Aparentemente no se puede hacer en C#, debe especificar cualquiera de los dos parámetros de tipo, o ninguno.

Y no parece ser apoyado por el CLR o bien, A<int>.B<> y A<string>.B<> se refieren al mismo tipo:

Type t1 = typeof(A<int>).GetNestedType("B`1"); 
Type t2 = typeof(A<string>).GetNestedType("B`1"); 
// t1.Equals(t2) is true 

El tipo envolvente de ambos tipos es A<> (tipo genérico abierto)

EDIT: más pruebas muestra que typeof(A<int>.B<string>) es en realidad un tipo genérico de aridad 2, no un tipo genérico anidada de aridad 1 ... typeof(A<int>.B<string>).GetGenericArguments() devuelve una matriz con typeof(int)ytypeof(string). Entonces typeof(A<int>.B<>) sería en realidad equivalente a (A.B)<int, >, que no es compatible (un tipo genérico no se puede cerrar parcialmente)

+4

Su observación es correcta. Debajo de las cubiertas, C .D es simplemente "C.D" . La forma C# de concebirlo como C .D es solo una ficción conveniente. –

+1

@Eric, gracias por la confirmación. Esperaba que vieras esta pregunta y arrojes algo de luz sobre ella ... Podría ser un buen tema para una publicación de blog si te faltan ideas;) –

+0

Tienes razón, por supuesto. Mi error fue suponer que 'typeof (A .B <>)' sería legal - Sabía que 'A .B ' se implementa como 'AB ', lo que significa que 'typeof (A .B <>) 'sería en realidad' AB 'que no parecía que debería ser legal. – configurator

3

¿Es esto lo que tiene en mente?

class AB<T, U> 
    { 
     protected T t; 
     U u; 
    } 

    class C<U> : AB<int, U> 
    { 
     public void Foo() 
     { 
     t = 5; 
     } 
    } 
+1

@downvoter: háblame. ¿Le gustaría ver la salida del reflector, el extracto de la especificación C#, alguna otra cosa? – GregC

+2

Parece que el OP está pidiendo una instancia de un objeto 'Type' que exprese algo así como' typeof (AB ) '. – Gabe