wake-up-neo.com

Warum sind const-Parameter in C # nicht zulässig?

Besonders für C++ - Entwickler sieht es seltsam aus. In C++ haben wir einen Parameter als const markiert, um sicherzustellen, dass sein Status in der Methode nicht geändert wird. Es gibt auch andere C++ - spezifische Gründe, wie das Übergeben von const ref, um ref zu passieren und sicherzustellen, dass der Status nicht geändert wird. Aber warum können wir nicht als Methodenparameter const in C # markieren?

Warum kann ich meine Methode nicht wie folgt deklarieren?

    ....
    static void TestMethod1(const MyClass val)
    {}
    ....
    static void TestMethod2(const int val)
    {}
    ....
97
Incognito

Zusätzlich zu den anderen guten Antworten füge ich noch einen weiteren Grund hinzu, warum C-Konstanz nicht in C # eingefügt werden sollte. Du sagtest:

wir markieren Parameter als const, um sicherzustellen, dass ihr Status in der Methode nicht geändert wird.

Wenn const das tatsächlich tun würde, wäre das großartig. Const macht das nicht. Der const ist eine Lüge!

Const gibt keine Garantie, die ich tatsächlich nutzen kann. Angenommen, Sie haben eine Methode, die einen konstanten Wert annimmt. Es gibt zwei Code-Autoren: die Person, die den Anrufer schreibt und die Person, die den Angerufenen schreibt . Der Autor des Angerufenen hat die Methode zu einer Konstante gemacht. Was können die beiden Autoren davon ausgehen, dass das Objekt unveränderlich ist?

Nichts. Dem Angerufenen steht es frei, die Konstante zu entfernen und das Objekt zu mutieren, sodass der Aufrufer keine Garantie hat , dass der Aufruf einer Methode, die eine Konstante annimmt, nicht mutiert es. Ebenso kann der Angerufene nicht davon ausgehen, dass sich der Inhalt des Objekts während der gesamten Aktion des Angerufenen nicht ändert. Der Angerufene könnte eine Mutationsmethode für einen Nicht-Konstanten-Alias ​​ des Konstanten-Objekts aufrufen, und jetzt hat das sogenannte Konstanten-Objekt geändert .

C-style const bietet keine Garantie dafür, dass sich das Objekt nicht ändert und daher beschädigt ist. Jetzt hat C bereits ein schwaches Typsystem, in dem Sie eine Neuinterpretation eines Double in ein Int vornehmen können, wenn Sie dies wirklich möchten. Es sollte daher nicht überraschen, dass es auch in Bezug auf const ein schwaches Typsystem hat. Aber C # wurde entwickelt, um ein gutes Typensystem zu haben, ein Typensystem, bei dem, wenn Sie sagen "diese Variable enthält einen String", dass die Variable enthält tatsächlich einen Verweis auf eine Zeichenfolge (oder null). Wir wollen auf keinen Fall einen C-Stil "const" Modifikator in das Typsystem setzen, weil wir nicht wollen, dass das Typsystem eine Lüge ist . Wir möchten, dass das Typsystem stark ist , damit Sie richtig argumentieren können über Ihren Code.

Const in C ist eine Richtlinie ; es bedeutet im Grunde "du kannst mir vertrauen, dass ich nicht versuche, dieses Ding zu mutieren". Das sollte nicht im Typsystem sein ; Das Zeug im Typensystem sollte eine Tatsache über das Objekt sein, das Sie können darüber nachdenken, keine Richtlinie zu seiner Verwendung.

Versteht mich nicht falsch. Nur weil const in C tief gebrochen ist, heißt das noch lange nicht, dass das ganze Konzept unbrauchbar ist. Was ich gerne sehen würde, ist eine tatsächlich korrekte und nützliche Form von "const" Annotation in C #, eine Annotation, mit der sowohl der Mensch als auch der Compiler den Code besser verstehen können und mit der die Laufzeit beispielsweise automatische Parallelisierung und andere erweiterte Optimierungen durchführen kann.

Stellen Sie sich zum Beispiel vor, Sie könnten eine Box um ein Stück Code "zeichnen" und sagen "Ich garantiere , dass dieses Stück Code keine Mutationen für irgendeinen ausführt Feld dieser Klasse "in einer Weise, die vom Compiler überprüft werden könnte. Oder zeichnen Sie eine Box mit der Aufschrift "Diese reine Methode mutiert den internen Zustand des Objekts, jedoch nicht in einer Weise, die außerhalb der Box beobachtet werden kann". Solch ein Objekt könnte nicht sicher automatisch mit mehreren Threads versehen werden, aber es könnte automatisch gespeichert werden . Es gibt alle Arten von interessanten Anmerkungen, die wir in Code einfügen könnten, um umfassende Optimierungen und ein tieferes Verständnis zu ermöglichen. Wir können es viel besser machen als die schwache C-artige const-Annotation.

Ich betone jedoch, dass dies nur Spekulation ist . Wir haben keine festen Pläne, diese Art von Funktion in eine hypothetische zukünftige Version von C # zu integrieren, falls es überhaupt eine gibt, die wir nicht auf die eine oder andere Weise angekündigt haben. Es ist etwas, das ich gerne sehen würde, und etwas, das die kommende Betonung auf Multi-Core-Computing erfordern könnte, aber keines davon sollte in irgendeiner Weise als Vorhersage oder Garantie für ein bestimmtes Merkmal oder eine zukünftige Richtung für C # ausgelegt werden.

Wenn Sie lediglich eine Annotation für die lokale Variable benötigen, die den Parameter "Der Wert dieses Parameters ändert sich nicht in der gesamten Methode" enthält, ist dies problemlos möglich. Wir könnten "readonly" -Locals und -Parameter unterstützen, die einmal initialisiert würden, sowie einen Fehler beim Kompilieren, der in der Methode geändert werden könnte. Die von der using-Anweisung deklarierte Variable ist bereits eine solche lokale Variable. Wir könnten allen Locals und Parametern eine optionale Annotation hinzufügen, damit sie sich wie "using" -Variablen verhalten. Es war noch nie ein Feature mit sehr hoher Priorität, daher wurde es noch nie implementiert.

59
Eric Lippert

Einer der Gründe, warum es in C # kein const correctness gibt, ist, dass es auf Laufzeitebene nicht existiert. Denken Sie daran, dass C # 1.0 keine Funktion hatte, es sei denn, es war Teil der Laufzeit.

Und einige Gründe, warum die CLR keine Vorstellung von der konstanten Korrektheit hat, sind zum Beispiel:

  1. Dies verkompliziert die Laufzeit. Außerdem hatte die JVM es auch nicht und die CLR startete im Grunde genommen als Projekt zum Erstellen einer JVM-ähnlichen Laufzeit, nicht einer C++ - ähnlichen Laufzeit.
  2. Wenn es auf Laufzeitebene eine konstante Korrektheit gibt, sollte es eine konstante Korrektheit in der BCL geben, da sonst die Funktion für .NET Framework ziemlich sinnlos ist.
  3. Aber wenn die BCL eine konstante Korrektheit erfordert, sollte jede Sprache über der CLR eine konstante Korrektheit unterstützen (VB, JavaScript, Python, Ruby, F # usw.). Das ist nicht es wird passieren.

Konstanten-Korrektheit ist so ziemlich eine Sprachfunktion, die nur in C++ vorhanden ist. Es läuft also so ziemlich auf die gleiche Argumentation hinaus, warum für die CLR keine überprüften Ausnahmen erforderlich sind (dies ist eine Java Nur-Sprache-Funktion)).

Ich glaube auch nicht, dass Sie in einer verwalteten Umgebung ein derart grundlegendes Typsystemfeature einführen können, ohne die Abwärtskompatibilität zu beeinträchtigen. Verlassen Sie sich also nicht darauf, dass jemals Konstanten-Korrektheit in die C # -Welt gelangt.

23
Ruben

Ich glaube, es gibt zwei Gründe, warum C # nicht const-korrekt ist.

Der erste ist Verständlichkeit. Nur wenige C++ - Programmierer verstehen die Konstantenrichtigkeit. Das einfache Beispiel für const int arg Ist niedlich, aber ich habe auch char * const * const arg Gesehen - einen konstanten Zeiger auf konstante Zeiger auf nicht konstante Zeichen. Die Konstanz von Zeigern auf Funktionen ist eine völlig neue Ebene der Verschleierung.

Der zweite Grund ist, dass Klassenargumente Referenzen sind, die als Wert übergeben werden. Dies bedeutet, dass es bereits zwei Konstanzstufen gibt, für die es kein offensichtlich klares Syntax gibt. Ein ähnlicher Stolperpunkt sind Sammlungen (und Sammlungen von Sammlungen usw.).

Die Konstanz ist ein wichtiger Bestandteil des C++ - Typensystems. Theoretisch könnte es zu C # hinzugefügt werden, als etwas, das nur zur Kompilierungszeit überprüft wird (es muss nicht zur CLR hinzugefügt werden und würde die BCL nicht beeinflussen, es sei denn, der Begriff der const-Member-Methoden wäre enthalten). .

Ich halte dies jedoch für unwahrscheinlich: Der zweite Grund (Syntax) wäre ziemlich schwierig zu lösen, was den ersten Grund (Verständlichkeit) noch problematischer machen würde.

11
Stephen Cleary

const bedeutet in C # "Konstante für die Kompilierungszeit", nicht "schreibgeschützt, aber möglicherweise durch anderen Code veränderbar" wie in C++. Ein grobes Analogon von C++ const in C # ist readonly, aber dieses gilt nur für Felder. Abgesehen davon gibt es in C # überhaupt keinen C++ - ähnlichen Begriff der konstanten Korrektheit.

Das Grundprinzip ist mit Sicherheit schwer zu sagen, da es viele mögliche Gründe gibt. Ich würde jedoch den Wunsch haben, die Sprache in erster Linie einfach zu halten, und unsichere Vorteile der Implementierung dieser zweiten.

5
Pavel Minaev