2010-07-10 4 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> 
{ 

} 

Soweit ich weiß, A<T1, T2> generischer Typ nicht ein tatsächlicher Typ ist, sondern ein Plan/Vorlage für eine tatsächliche Art, also warum typeof es als Parameter übernimmt (da soweit ich weiß, typeof akzeptiert als Parameter tatsächliche Typen)?Wenn A <T1,T2> eine Vorlage für den tatsächlichen Typ ist, warum ist typeof (A <,>) zulässig?

Vielen Dank

+0

sehr gute Frage +1 – nawfal

Antwort

4

In Reflexion die unkonstruierten gattungs sagen C<> mit dem Instanztyp C<T> verschmelzt wird.

Dies ist vielleicht weniger als theoretisch rein; Ich denke an diese als sehr unterschiedliche Entitäten. Ich denke an eine als Symbol "C mit einem Typ Parameter" und die andere als Kompilierzeit TypC<T>. In Code sind C<> und C<T> nicht Synonyme für einander; Sie können ein Feld des letzteren Typs erstellen, wenn T im Gültigkeitsbereich ist, aber Sie können niemals ein Feld des vorherigen Typs erstellen.

Dass die Reflektionsbibliothek Ihnen den Typ des Instanztyps gibt, wenn Sie nach dem unkonstruierten Typ fragen, ist jedoch nicht alles schlecht. Was würden Sie mit dem unkonstruierten Typ tun? Es gibt nichts, was du wirklich damit tun kannst. Aber mit dem Instanztyp können Sie hier "substitute int for T" sagen.

Der echte Vorteil des Erhaltens C<T>, wenn Sie nach typeof(C<>) fragen, ist, dass dies Ihnen immer den unkonstruierten Typ gibt. Vergleichen:

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

Wenn Sie anrufen CT, was werden Sie es auf anrufen? Es gibt keinen Typ C<T>, um CT anzurufen. Sie können C<int>.CT anrufen. In diesem Fall erhalten Sie C<int>, nicht C<T>. Der einzige Weg, um den Typ C<> mit T konstruiert zu bekommen, ist typeof(C<>) zu fragen.

Macht das Sinn?

Ich habe noch nicht abgedeckt Reflexion (Ich habe eine vage Vorstellung davon, was es ist)

Reflexion ist einfach die Bibliothek von Code, den Sie Informationen über Ihren Code im Code erhalten kann selbst . "typeof" gibt Ihnen ein Type-Objekt, über das Sie "nachdenken" können, um Informationen über den Typ zu erhalten.

Ich bin mir nicht sicher, ob ich verstehe, was du meinst durch „auch wenn T in ihrem Umfang nicht ist“

Die Art, wie ich sagte, es ist verwirrend. Ich habe es umformuliert.

+0

1 - "Macht das Sinn?" Etwas, aber ich habe noch nicht über Reflektion berichtet (ich habe eine vage Vorstellung davon, was es ist) und ich bin mehr auf einer dummen Seite. 2 - "Der wirkliche Vorteil ist, dass Sie mit typeof (C <>) das Typobjekt für C erhalten, auch wenn T nicht im Bereich" Ich bin mir nicht sicher, ich verstehe, was Sie meinen "auch wenn T ist Nicht im Anwendungsbereich"? 2 - "Dass die Reflektionsbibliothek Ihnen den Typ des Instanztyps gibt, wenn Sie nach dem unkonstruierten Typ fragen, ist jedoch nicht alles schlecht."Ich nehme an, dass Sie hier nicht von typeof sprechen (A <,>), da Sie dadurch keine Instanz vom Typ A erhalten. flockofcode

+0

" Die Reflexions-Bibliothek gibt Ihnen den Typ des Instanztyps, wenn Sie nach dem Unstrukturierten fragen Typ ist jedoch nicht alles schlecht. "Die verwendete Terminologie ist etwas verwirrend. Sie sagen, typeof (C <>) gibt den Typ eines Instanztyps zurück und gibt daher den Typ C zurück, wobei T noch nicht spezifiziert ist Mein Verständnis Sie implizieren, dass C ist ein Instanztyp, während meines Wissens Instanztypen alle ihre Typparameter bestimmt haben ?! – flockofcode

+1

@flockofcode: In der Tat ist die Terminologie * sehr * verwirrend. Die Spezifikation definiert den "Instanztyp" eines generischen Typs als Typ, bei dem es sich um den * Kompilierzeit * -Typ des mit seinen Typparametern konstruierten Typs handelt, beispielsweise in Klasse C {C x; } Der * Kompilierzeit * Typ von x ist der * Instanztyp * von C-mit-einem-Typ-Parameter. Der Laufzeittyp von x hängt natürlich von dem Typargument ab, das für T –

4

Es wird angenommen, weil es ein generischer Typ ist.

Es ist ein offener generischer Typ (wo sie keine Parameter eingeben), aber ein Typ trotzdem.

Siehe die Diskussion here (Was genau ist ein "offener generischer Typ").

Und auf MSDN (typeof):

Der typeof-Operator auch auf offene generische Typen verwendet werden können.

+0

1-Würden Sie zustimmen, dass streng genommen A ist kein tatsächlicher Typ? 2 - Was ist der Unterschied zwischen einem offenen generischen Typ und einem offenen generischen Typ? – flockofcode

+3

@flockofcode - 1. offene generische Typen sind Typen. Sie können nicht ohne Angabe von Typparametern instanziiert werden, sie sind jedoch immer noch Typen. 2. Ein offener konstruierter Typ ist, wenn mindestens einer der generischen Typen nicht angegeben wurde. Siehe hier: http://en.csharp-online.net/Generic_types – Oded

+0

1) "offene generische Typen sind Typen" Soweit ich sagen kann, gibt es keine Möglichkeit für eine Methode, als einen ihrer Parameter einen offen konstruierten generischen Typ zu haben ? 2) So sagen wir, dass A {} ist ein offener konstruierter Typ, während A ist offener generischer Typ. Aber könnten wir nicht argumentieren, dass A auch ein offener konstruierter Typ ist (wenn nicht, dann sollte die Definition eines offenen konstruierten Typs sagen, dass für den offenen konstruierten Typ mindestens eine seiner Argumenttypen angegeben sein muss, ansonsten ist es ein offener generischer Typ) – flockofcode

1

Da A<T1, T2> ist eine offene generische, die die documentation explizit sagt, dass es unterstützt.

+1

Was ist der Unterschied zwischen dem offenen generischen Typ und dem offen konstruierten generischen Typ? – flockofcode

Verwandte Themen