Einschränkungen für generische Klasseneinschränkungen auf Klassen- und Methodenebene

8

Betrachten Sie die folgende Klasse:

%Vor%

Beachten Sie, dass ich das generische Klassen-Argument TBase auf eine Klasse eingeschränkt habe: where TBase : class
Ich habe auch das TDerived generische Methodenargument auf TBase oder etwas davon abgeleitet: where TDerived : TBase .

eingeschränkt

Ich bekomme einen Fehler in der as TDerived -Zeile:

  

Der Typparameter 'TDerived' kann nicht mit dem 'as' -Operator verwendet werden, da er weder eine Klassenbeschränkung noch eine 'class'-Integritätsregel

enthält

Ich verstehe, dass ich den Constraint class hinzufügen muss, um den Fehler zu vermeiden, also bekomme ich:

%Vor%

Warum muss ich dies tun, wenn TBase bereits auf eine Klasse beschränkt ist und TDerived auf eine TBase beschränkt oder davon abgeleitet ist?

    
George Duckett 17.01.2012, 16:48
quelle

2 Antworten

8

UPDATE: Diese Frage war das Thema meines Blogs am 19. September 2011 . Danke für die tolle Frage!

  

Warum muss ich das tun, wenn TBase bereits als Klasse definiert ist und TDerived gezwungen ist, eine TBase zu sein oder davon abgeleitet zu sein?

Weil ein Werttyp von einem Referenztyp abgeleitet werden kann. int wird von den Referenztypen object und System.ValueType abgeleitet und implementiert eine Anzahl von Schnittstellen. Das macht int nicht zu einem Referenztyp.

Es ist absolut legal, dass Sie SomeMethod<int> für eine Instanz von DerivedClassPool<object> aufrufen, weil int von object abgeleitet ist.

Nun, dort sind Fälle, in denen Ihre Kritik gerechtfertigt wäre. Man kann Situationen konstruieren, in denen zwei Typparameter so zusammenhängen, dass beide logisch nur Referenztypen sein können, aber nur einer von ihnen von der Sprache als "vom Referenztyp bekannt" klassifiziert wird.

Als Übung für den Leser: Kannst du einen finden? Es könnte notwendig sein, Abschnitt 10.1.5 der Spezifikation für eine genaue Definition von "bekannt als Referenztyp" sorgfältig zu lesen.

    
Eric Lippert 17.01.2012, 16:56
quelle
2

Weil TBase eine Schnittstelle sein könnte und daher TDerived ein Werttyp sein könnte.

    
Andras Zoltan 17.01.2012 16:58
quelle

Tags und Links