2010-07-10 12 views
7
class Program 
{ 
    static void Main(string[] args) 
    { 
     Type t = typeof(A<,>); 
     Console.WriteLine(typeof(A<,>)); // prints A'2[T1,T2] 
    }  
} 

class A<T1,T2> 
{ 

} 

Por lo que yo sé, el tipo genérico de A<T1, T2> no es un tipo real, sino más bien un modelo/plantilla para un tipo real, ¿por qué lo hace typeof acepto como un parámetro (ya que por lo que yo sé, typeof acepta como tipos de parámetros reales)?Si A <T1,T2> es una plantilla para el tipo real, ¿por qué se permite typeof (A <,>)?

Gracias

+0

muy buena pregunta +1 – nawfal

Respuesta

4

En reflexión tipo genérico sin construir, dicen C<> se combinó con el tipo ejemploC<T>.

Esto es quizás menos que teóricamente puro; Pienso en estas como entidades muy diferentes. Pienso en uno como el símbolo "C con un parámetro de tipo" y el otro como tiempo de compilación tipoC<T>. En el código, C<> y C<T> no son sinónimos el uno para el otro; puedes hacer un campo del último tipo si T está dentro del alcance, pero nunca puedes hacer un campo del tipo anterior.

Sin embargo, el hecho de que la biblioteca de reflexión proporcione el tipo del tipo de instancia cuando solicita el tipo no construido no es del todo malo. ¿Qué haría do con el tipo no construido? No hay nada que realmente puedas hacer con eso. Pero con el tipo de instancia, puede decir "sustituir int para T" aquí.

El beneficio real de obtener C<T> cuando solicita typeof(C<>) es que esto siempre le proporciona el tipo no construido. Compare:

class C<T> 
{ 
    public static Type CT() { return typeof(C<T>); } 
    public static Type JustC() { return typeof(C<>); } 
} 

Cuando se llama CT, ¿qué vas a llamarlo en? No hay ningún tipo C<T> para llamar a CT. Puede llamar al C<int>.CT en cuyo caso recibirá C<int>, no C<T>. La única forma de obtener el tipo C<> construido con T es solicitar typeof(C<>).

¿Tiene sentido?

todavía no he cubierto la reflexión (tengo una vaga idea de lo que es)

La reflexión es simplemente la biblioteca de código que le permite obtener información acerca de su código en el propio código . "typeof" le da un objeto Type que luego puede "reflejar" para encontrar información sobre el tipo.

no estoy seguro de entender lo que quiere decir con "T incluso cuando no está en el ámbito"

La forma en que dijo que era confuso. Lo he reformulado.

+0

1 - "¿Eso tiene sentido?" Un poco, pero aún no he cubierto el reflejo (tengo una vaga idea de lo que es) y estoy más en un lado estúpido. 2 - "El beneficio real es que typeof (C <>) le permite obtener el tipo de objeto para C incluso cuando T no está en el alcance" No estoy seguro de entender lo que quiere decir con "incluso cuando T no en su alcance"? 2 - "Que la biblioteca de reflexión le proporcione el tipo del tipo de instancia cuando pregunta por el tipo no construido no es del todo malo."Supongo que aquí no está hablando de typeof (A <,>), ya que esto no le da una instancia de tipo A flockofcode

+0

" Que la biblioteca de reflexión le proporcione el tipo del tipo de instancia cuando pregunta por la no reconstruida Sin embargo, el tipo no es del todo malo. "La terminología que utiliza es un poco confusa. Usted dice typeof (C <>) devuelve el tipo de un tipo de instancia, por lo que devuelve el tipo de C , donde T aún no se ha especificado. Según entiendo, usted está insinuando que C es un tipo de instancia, mientras que para mi conocimiento los tipos de instancias tienen todos sus parámetros de tipo determinados ?! – flockofcode

+1

@flockofcode: De hecho, la terminología es * muy * confusa. La especificación define el "tipo de instancia" de un tipo genérico como el tipo que es el * tiempo de compilación * del tipo construido con sus parámetros de tipo. Por ejemplo, en la clase C {C x; } el * tipo * de compilación * de x es el * tipo de instancia * de C-con-un-tipo-parámetro. El tipo de tiempo de ejecución de x dependerá, por supuesto, del argumento de tipo sustituido por T –

4

Se acepta porque es un tipo genérico.

Es un tipo genérico abierto (donde no se han especificado los parámetros de tipo), pero un tipo sin embargo.

Consulte la discusión here (¿Qué es exactamente un "tipo genérico abierto").

Y en MSDN (typeof):

El operador typeof también se puede utilizar en los tipos genéricos abiertos.

+0

1-¿Será usted de acuerdo en que estrictamente hablando A no es un tipo real? 2-¿Cuál es la diferencia entre el tipo genérico abierto y el tipo genérico construido abierto? – flockofcode

+3

@flockofcode - 1. abrir tipos genéricos son tipos. No se pueden crear instancias sin proporcionar parámetros de tipo, pero siguen siendo tipos. 2. Un tipo abierto construido es cuando al menos uno de los tipos genéricos no ha sido especificado. Vea aquí: http://en.csharp-online.net/Generic_types – Oded

+0

1) "tipos genéricos abiertos son tipos" Por lo que puedo decir, no hay forma de que el método tenga como uno de sus parámetros un tipo genérico abierto construido ? 2) Entonces decimos que A {} es un tipo abierto construido, mientras que A es un tipo genérico abierto. Pero no podríamos argumentar que A es también un tipo construido abierto (si no, la definición de un tipo abierto construido debería decir que el tipo construido abierto debe tener al menos uno de sus argumentos de tipo especificado, de lo contrario es un tipo genérico abierto))? – flockofcode

1

Porque A<T1, T2> es un genérico abierto, que el documentation dice explícitamente que es compatible.

+1

¿Cuál es la diferencia entre el tipo genérico abierto y el tipo genérico abierto abierto? – flockofcode

Cuestiones relacionadas