In seinem Buch bezieht sich Jon Skeet auf 7 Einschränkungen impliziter Typisierung. Ich brauche Klarheit über die letzten beiden:
A. Der Typ, den die Variable haben soll, ist der Kompilierzeittyp des Initialisierungsausdrucks.
B. Der Initialisierungsausdruck enthält keine Die Variable wird deklariert.
Das Buch behandelt das Material in der gleichen Reihenfolge wie es veröffentlicht wurde (C # 2 vor C # 3). An diesem Punkt wurde C # 4 nicht eingeführt, daher nehme ich an, dass sich A nicht auf dynamic
bezieht. Also, wann würde sich der Kompilierzeittyp vom Ausführungszeittyp des Initialisierungsausdrucks unterscheiden?
Wie für B , wann kann ein Initialisierungsausdruck die Deklaration der Variablen beinhalten?
Was B betrifft, hat Henk eine perfekte Antwort gegeben (edit: es ist jetzt entfernt), obwohl ich es seltsam finde, dass int x = x = 1;
kompiliert. (Ich hätte gedacht, dass x erst nach dem Initialisierer als deklariert gilt. Oh, nun ja.) Seine Antwort war:
In Bezug auf A und Ihre Frage, wann der Kompilierungszeittyp nicht mit dem Ausführungszeittyp übereinstimmt, sehen Sie hier ein Beispiel, wo sie sich unterscheiden würden:
%Vor%... und diese Methode auf fooFactory wird als ... implementiert.
%Vor%Hier ist foo der Typ FooBase (der eine Schnittstelle, eine abstrakte Klasse oder eine unverschlossene konkrete Klasse sein kann), und (ohne Casting) sind nur seine Funktionen verfügbar. Offensichtlich implementiert oder erbt FooSubtype von FooBase.
Der Typ, den foo zur Laufzeit enthält, kann hier nur unterschieden werden, weil ich die Implementierung von GetFoo () zeige, aber nicht vom Compiler überprüft wird. Tatsächlich ist die Implementierung möglicherweise nicht einmal verfügbar (könnte in einer anderen Assembly sein) oder sie kann variieren (könnte virtuell sein). Um den Kompilierzeittyp von GetFoo () und damit von foo zu bestimmen, ist nur die Methodendeklaration relevant.
Meine Gedanken für A :
Es ist nicht so, dass sich die Kompilierzeit vom Ausführungstyp unterscheidet, denn selbst wenn der Ausführungstyp nicht mit dem Kompilierungstyp übereinstimmt (wie bei jeder Methode, deren Rückgabetyp ein abstrakter Typ ist), können Sie die Variable nicht deklarieren mit dem Ausführungstyp sowieso mit expliziter Typisierung.
Aber Sie könnten die Variable mit einem abstrakteren statischen Typ deklarieren, auch wenn der dynamische real -Typ zur Kompilierzeit definiert werden kann. Betrachten Sie zum Beispiel:
%Vor% Warum möchten Sie das tun? Wenn Ihr MyNewSomething
explizit ISomething
implementiert, dann müssten Sie einen Cast erstellen, um es wie ein ISomething
zu verwenden, wenn es in einem var deklariert wird. Hier ist die Besetzung immer noch gemacht, aber Sie sehen das eher nicht hässlich:
Ein komplizierteres Beispiel ist, dass sich der Initialisierungscode später ändern kann und Sie möchten sicherstellen, dass Sie ab diesem Zeitpunkt nur noch a
als ISomething
verwenden und niemals die Details von MyOwnSomething
sehen. Typ oder andere Schnittstellen, die es möglicherweise implementiert, so dass Änderungen am Initialisierungstyp den Code nicht beschädigen.