Warum gibt es keinen Compilerfehler, wenn ich eine Klasse in eine Schnittstelle umwandle, die sie nicht implementiert?

8

Wenn ich eine ungültige Umwandlung von einer Klasse in eine Schnittstelle versuche, dann meldet sich der Compiler nicht (der Fehler tritt zur Laufzeit auf); Es tut jedoch, wenn ich eine ähnliche Umwandlung in eine abstrakte Klasse versuche.

%Vor%

Warum lehnt der Compiler den Cast von Foo zu IBar ab, wenn er (scheinbar?) ungültig ist? Oder, um die Frage umzudrehen, wenn der Compiler diese "ungültige" Umwandlung in die Schnittstelle IBar erlaubt, warum erlaubt er nicht die ähnliche "ungültige" Umwandlung in die abstrakte Klasse aBaz ?

    
McGarnagle 09.09.2012, 01:09
quelle

3 Antworten

7

Sie müssen das Vererbungssystem von .Net verstehen, um zu sehen, warum dies sinnvoll ist. In .NET kann eine Klasse nur von einer Basisklasse erben, aber eine beliebige Anzahl von Schnittstellen implementieren.

%Vor%

In dem extrem einfachen ursprünglichen Beispiel in der Frage scheint es, als ob der Compiler erkennen könnte, dass diese Instanz von foo niemals in IBar umgewandelt werden kann, aber das ist eher eine "nette" Warnung als eine Frage von Sprachkorrektheit.

    
BitwiseMan 09.09.2012, 01:42
quelle
6

Der ganze Sinn eines Cast ist es, diesen Compilerfehler zu unterdrücken.
(zB wenn Sie wissen, dass foo tatsächlich eine Instanz eines Subtyps ist, der die Schnittstelle implementiert)

Wenn der Compiler beweisen kann, dass der Cast nicht erfolgreich ist, wird immer noch ein Fehler ausgegeben. (Wenn Sie beispielsweise in eine Klasse umgewandelt haben, die nicht in ihrer Hierarchie liegt)

    
SLaks 09.09.2012 01:12
quelle
5

Um zu zeigen, dass der Compiler nicht dumm ist, gibt es einen actualy-Fall, bei dem die Umwandlung zum Zeitpunkt der Kompilierung fehlschlägt: Wenn der Compiler beweisen kann, dass keine anderen Klassen von der Klasse abgeleitet werden können, wird er zum Zeitpunkt der Kompilierung nicht an Interfaces übergeben:

%Vor%

Im ersten Fall ( NoBar ) ist die Klasse explizit versiegelt (und daher können keine abgeleiteten Klassen IFoo implementieren) und der Compiler weiß, dass er IBar selbst nicht implementiert - er kann daher zur Kompilierungszeit fehlschlagen. Der zweite Fall ( NoBarValue ) ist ähnlich mit dem Unterschied, dass Werttypen (struct) implizit versiegelt sind.

    
Alexei Levenkov 09.09.2012 03:57
quelle