Ok, also hier ist die Frage ... ist das neue Keyword veraltet?
Betrachte in C # (und Java, glaube ich) gibt es strenge Regeln für Typen. Klassen sind Referenztypen und können nur auf dem Heap erstellt werden. POD-Typen werden auf dem Stapel erstellt. Wenn Sie sie auf dem Heap zuweisen möchten, müssen Sie sie in einen Objekttyp einbetten. In C # ist structs
die Ausnahme, sie können auf dem Stack oder Heap erstellt werden.
Macht es angesichts dieser Regeln Sinn, dass wir immer noch das neue Keyword verwenden müssen? Wäre es nicht sinnvoll für die Sprache, die richtige Zuweisungsstrategie basierend auf dem Typ zu verwenden?
Zum Beispiel müssen wir jetzt schreiben:
%Vor%statt
%Vor%oder auch nur
%Vor%Der Compiler würde, basierend darauf, dass der erzeugte Typ ein Referenztyp ist, weitermachen und den Speicher für x auf dem Heap reservieren.
Dies gilt auch für andere Sprachen wie Ruby, PHP, et al. C / C ++ ermöglicht dem Programmierer mehr Kontrolle darüber, wo Objekte erstellt werden, daher gibt es einen guten Grund, das neue Schlüsselwort zu verlangen.
Ist new
nur ein Überbleibsel aus den 60ern und unser C-basiertes Erbe?
in diesem Fall SomeClassType()
könnte eine andere Methode sein, wie würde der Compiler wissen, ob er diese Methode aufrufen oder eine neue Klasse erstellen soll.
Dies ist nicht sehr nützlich, die meisten Leute deklarieren ihre Variablen wie diese und füllen sie manchmal später, wenn sie müssen. Es wäre also nicht sinnvoll, jedes Mal, wenn Sie eine Variable deklarieren, eine Instanz im Speicher zu erstellen.
Ihre dritte Methode funktioniert nicht, da wir manchmal ein Objekt eines Typs definieren und es einer Variablen eines anderen Typs zuweisen wollen. Zum Beispiel:
%Vor%Ich möchte einen Stream-Typ (vielleicht irgendwo weitergeben), aber intern möchte ich einen NetworkStream-Typ.
Auch oft erstelle ich beim Aufruf einer Methode ein neues Objekt:
%Vor%macht das so:
%Vor%ist sehr verwirrend. Erstelle ich ein Objekt oder rufe ich eine Methode auf, wenn ich NetworkStream () sage?
Wenn Sie SomeClassType x;
einfach schreiben und automatisch initialisieren könnten, würden Konstruktoren mit beliebigen Parametern nicht berücksichtigt. Nicht jeder SomeClassType
wird einen parameterlosen Konstruktor haben; Wie würde der Compiler wissen, welche Argumente zu liefern?
Wie würden Sie dieses Objekt mit nur Repository rep;
instanziieren? Es erfordert ein abhängiges Objekt, um ordnungsgemäß zu funktionieren.
Ganz zu schweigen davon, dass Sie Code wie folgt schreiben möchten:
%Vor%Möchten Sie wirklich, dass es für Sie automatisch initialisiert?
Wenn Sie SomeClassType x = SomeClassType()
nur geschrieben haben, macht dies keinen Unterschied zwischen einem Konstruktor und einer Methode im Bereich.
Allgemeiner :
Ich denke, es gibt ein grundlegendes Missverständnis darüber, wofür das new
Keyword ist. Die Tatsache, dass Werttypen auf dem Stapel zugeordnet und "Referenztypen" auf dem Heap zugeordnet sind, ist ein Implementierungsdetail . Das Schlüsselwort new
ist Teil der Spezifikation . Als Programmierer ist es egal, ob sie auf dem Heap oder Stack (meistens) zugeordnet sind, aber Sie müssen angeben, wie das Objekt initialisiert wird .
Es gibt auch andere gültige Arten von Initialisierern, wie:
%Vor% Voilà, eine Initialisierung ohne new
. In diesem Fall war der Compiler intelligent genug, um es herauszufinden, weil Sie einen Literalausdruck angegeben haben, der das gesamte Objekt definiert.
Also denke ich, meine "Antwort" ist, mach dir keine Sorgen darüber, wo das Objekt memory-weise existiert; Verwenden Sie das Schlüsselwort new
wie vorgesehen, als Objektinitialisierer für Objekte, die initialisiert werden müssen.
Für den Anfang:
%Vor%ist nicht initialisiert, daher sollte kein Speicher zugewiesen werden.
Abgesehen davon, wie vermeiden Sie Probleme, wenn es eine Methode mit dem gleichen Namen wie die Klasse gibt.
Sagen Sie, Sie schreiben etwas Code:
%Vor%und alles ist schön und lustig.
Sie schreiben später eine neue Klasse:
%Vor% Plötzlich ist Ihre int hello = World()
-Zeile mehrdeutig.
Aus Leistungsgründen könnte dies eine schlechte Idee sein. Wenn Sie beispielsweise möchten, dass x eine Referenz für ein Objekt ist, das bereits erstellt wurde, wäre es eine Verschwendung von Speicher- und Prozessorzeit, ein neues Objekt zu erstellen und es sofort zu entsorgen.
Wäre es nicht sinnvoll für die Sprache, um die richtige Zuordnung zu verwenden Strategie basierend auf dem Typ?
Genau das tut der C # -Compiler / Runtime bereits. Das Schlüsselwort new
ist nur die Syntax zum Konstruieren eines Objekts auf die für dieses Objekt sinnvolle Weise.
Wenn Sie das Schlüsselwort new
entfernen, wird es weniger offensichtlich, dass ein Konstruktor aufgerufen wird. Für ein ähnliches Beispiel betrachten Sie out
parameters:
Der Compiler weiß bereits, dass val
ein out
ist. Wenn du es nicht sagst, beschwert es sich. Aber es macht den Code lesbarer, um es zu sagen.
Zumindest ist das die Rechtfertigung - in modernen IDEs konnten diese Dinge neben dem eigentlichen eingefügten Text auch anders gefunden und hervorgehoben werden.
Ist neu, nur ein Überbleibsel aus den 60er Jahren und unser C-basiertes Erbe?
Definitiv nicht. C hat kein new
Schlüsselwort.
Ich habe seit einigen Jahren mit Java programmiert und es ist mir egal, ob mein Objekt auf dem Heap oder dem Stack ist. Aus dieser Perspektive ist es mir egal, new
einzugeben oder es nicht einzugeben.
Ich denke, das wäre für andere Sprachen relevanter.
Das einzige, was mich interessiert, ist, dass die Klasse die richtigen Operationen hat und meine Objekte richtig erstellt werden.
Übrigens, ich benutze (oder versuche), das Schlüsselwort new
nur in der Fabrik zu verwenden, damit mein Client trotzdem so aussieht
Siehe: Effektiver Java-Artikel: 1
Wenn Sie keinen parameterlosen Konstruktor haben, könnte das hässlich werden.
Wenn Sie mehrere Konstruktoren haben, könnte das wirklich hässlich werden.
Tags und Links java c# language-design