Wenn wir unsere Schnittstellen in C# 4.0 definieren, dürfen wir jeden generischen Parameter als in
oder out
kennzeichnen. Wenn wir versuchen, einen generischen Parameter als out zu setzen, und das zu einem Problem führen würde, löst der Compiler einen Fehler aus, der uns das nicht erlaubt.Kovarianz und Kontravarianz-Inferenz in C# 4.0
Frage:
Wenn der Compiler hat Weisen Folgern, was gültige Verwendungen für beide covariance
sind (out
) und contravariance
(in
), warum wir Schnittstellen als solche zu kennzeichnen müssen? Wäre es nicht genug, die Schnittstellen wie immer zu definieren, und wenn wir versuchen, sie in unserem Client-Code zu verwenden, einen Fehler melden, wenn wir versuchen, sie auf unsichere Weise zu verwenden?
Beispiel:
interface MyInterface<out T> {
T abracadabra();
}
//works OK
interface MyInterface2<in T> {
T abracadabra();
}
//compiler raises an error.
//This makes me think that the compiler is cappable
//of understanding what situations might generate
//run-time problems and then prohibits them.
Auch
ist es nicht, was Java funktioniert in der gleichen Situation? Von was ich mich erinnere, tun Sie nur etwas wie
IMyInterface<? extends whatever> myInterface; //covariance
IMyInterface<? super whatever> myInterface2; //contravariance
Oder mische ich Dinge?
Dank
Ich denke, seine zweite Frage war eher wie "Wie unterscheidet sich C# Varianz Annotationen von Javas Wildcard-Typen?" – Gabe
@Gabe: C# tut * Deklaration-Site * Varianz. Java macht * Call-Site * Varianz. Call-Site-Varianz ist eine interessante Idee, um sicher zu sein, aber es fühlt sich komisch an, eine Typ-Variante zu haben, basierend darauf, wie sie an einer bestimmten Site verwendet wird, im Gegensatz zu dem, wie sie definiert ist. –
Ja, ich bekomme jetzt das Problem mit der Java-Nutzung. Es hat den Vorteil, dass man die Parameter der Schnittstelle nicht als "in" oder "out" angeben muss, aber dann könnte ein Client ihm etwas Nutzen geben, das später möglicherweise nicht überliefert wird, wenn ich meine Schnittstelle aktualisieren möchte. –