Welche Designentscheidungen sprachen dafür, void
nicht konstruierbar zu sein und nicht als generischer Typ zugelassen zu werden? Immerhin ist es nur ein besonderes struct
Leerzeichen und hätte die totale PITA vermieden, eindeutige Func
und Action
delegierte Personen zu haben.
(C ++ erlaubt explizite void
Rückgaben und erlaubt void
als Template-Parameter)
c#
.net
language-design
Thomas Owens
quelle
quelle
Antworten:
Das grundlegende Problem bei "void" ist, dass es nicht dasselbe bedeutet wie jeder andere Rückgabetyp. "void" bedeutet "Wenn diese Methode zurückgibt, gibt sie überhaupt keinen Wert zurück." Nicht null; null ist ein Wert. Es wird überhaupt kein Wert zurückgegeben.
Dies bringt das Typensystem wirklich durcheinander. Ein Typensystem ist im Wesentlichen ein System, mit dem logisch abgeleitet werden kann, welche Operationen für bestimmte Werte gültig sind. Eine void return-Methode gibt keinen Wert zurück. Die Frage "Welche Operationen sind für dieses Ding gültig?" macht überhaupt keinen Sinn. Es gibt kein "Ding" für eine Operation, gültig oder ungültig.
Außerdem wird dadurch die Laufzeit etwas heftiger durcheinander gebracht. Die .NET-Laufzeit ist eine Implementierung des Virtual Execution System, das als Stack-Maschine spezifiziert ist. Dies ist eine virtuelle Maschine, bei der alle Vorgänge hinsichtlich ihrer Auswirkung auf einen Auswertungsstapel charakterisiert sind. (Natürlich wird die Maschine in der Praxis auf einer Maschine mit Stapel und Registern implementiert, aber das virtuelle Ausführungssystem nimmt nur einen Stapel an.) Der Effekt eines Aufrufs einer ungültigen Methode ist grundsätzlichanders als die Auswirkung eines Aufrufs einer nicht ungültigen Methode; Bei einer nicht leeren Methode wird immer etwas auf den Stapel gelegt, das möglicherweise entfernt werden muss. Eine Void-Methode legt niemals etwas auf den Stapel. Daher kann der Compiler nicht alle ungültigen und nicht ungültigen Methoden gleich behandeln, wenn der zurückgegebene Wert der Methode ignoriert wird. Wenn die Methode ungültig ist, gibt es keinen Rückgabewert, sodass kein Pop vorhanden sein darf.
Aus all diesen Gründen ist "void" kein Typ, der instanziiert werden kann. es hat keine Werte , das ist der springende Punkt. Es kann nicht in ein Objekt konvertiert werden, und eine Methode zur Rückgabe von Leerräumen kann niemals polymorph mit einer Methode ohne Rückgabe von Leerräumen behandelt werden, da dadurch der Stapel beschädigt wird!
Daher kann void nicht als Typargument verwendet werden, was, wie Sie bemerken, eine Schande ist. Das wäre sehr praktisch.
Im Nachhinein wäre es für alle Beteiligten besser gewesen, wenn eine Methode zur Rückgabe von Leerräumen automatisch "Unit" zurückgegeben hätte, einen magischen Singleton-Referenztyp. Sie würden dann wissen, dass jeder Methodenaufruf etwas auf den Stapel legt , dass jeder Methodenaufruf etwas zurückgibt, das einer Variablen des Objekttyps zugewiesen werden könnte , und natürlich könnte Unit als Typargument verwendet werden Es müssen keine separaten Aktionstypen und Funktionstypen für Stellvertreter vorhanden sein. Leider ist das nicht die Welt, in der wir uns befinden.
Weitere Gedanken in diesem Sinne finden Sie unter:
quelle
Void
sollte es in Ordnung sein, als unendliche Anzahl von Argumenten innerhalb von 0 Stapelbytes übergeben zu werden. Wenn eine Struktur konvertiert werden mussobject
oder eine Methode (zum Abrufenthis
) aufgerufen werden muss, wurde sie mit der Angabe einesType
Verweises vor dem Feldbereich des Speichers (für viele CLR-Implementierungen) auf den Heap gesetzt und konnte daher ordnungsgemäß behandelt werden. Typ ist für mich nur eine Gruppierung von Objekten, die durch einige Merkmale (Felder) unterschieden werden können.Void
ist nur ein Objekt.void
ein leerer Werttyp wäre, würde diese Anweisung zu Null-Anweisungen von Maschinencode führen. Nicht sehr nützlich für hartcodierte Typen vonVoid
, aber nützlich in Fällen, in denen ein Typ mehrere generische Parameter hat, einige jedoch in bestimmten Fällen nicht benötigt werden.Von: http://connect.microsoft.com/VisualStudio/feedback/details/94226/allow-void-to-be-parameter-of-generic-class-if-not-in-c-then-just-in- Laufzeit
Ich kann nicht für mein Leben sehen, wie leer eine Sicherheitslücke ist, aber ... so steht es.
quelle