Es sieht besonders für C ++ - Entwickler seltsam aus. In C ++ haben wir einen Parameter als markiert const
, um sicherzustellen, dass sein Status in der Methode nicht geändert wird. Es gibt auch andere C ++ - spezifische Gründe, z. B. das Übergeben const ref
, um ref zu übergeben und sicherzustellen, dass der Status nicht geändert wird. Aber warum können wir in C # nicht als Methodenparameter const markieren?
Warum kann ich meine Methode nicht wie folgt deklarieren?
....
static void TestMethod1(const MyClass val)
{}
....
static void TestMethod2(const int val)
{}
....
c#
language-agnostic
language-design
Inkognito
quelle
quelle
Antworten:
Zusätzlich zu den anderen guten Antworten werde ich noch einen weiteren Grund hinzufügen, warum C-artige Konstanz nicht in C # eingefügt werden sollte. Du sagtest:
Wenn const das tatsächlich tun würde, wäre das großartig. Const macht das nicht. Die Konstante ist eine Lüge!
Const bietet keine Garantie dafür, dass ich sie tatsächlich verwenden kann. Angenommen, Sie haben eine Methode, die eine konstante Sache akzeptiert. Es gibt zwei Codes Autoren: die Person , die das Schreiben Anrufer und die Person , die das Schreiben Angerufenen . 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 wegzuwerfen und das Objekt zu mutieren, sodass der Aufrufer keine Garantie dafür hat, dass der Aufruf einer Methode, die eine Konstante verwendet, diese tatsächlich nicht mutiert. Ebenso kann der Angerufene nicht davon ausgehen, dass sich der Inhalt des Objekts während der Aktion des Angerufenen nicht ändert. Der Angerufene könnte eine Mutationsmethode für einen nicht konstanten Alias des const-Objekts aufrufen , und jetzt hat sich das sogenannte const-Objekt geändert .
C-style const bietet keine Garantie dafür, dass sich das Objekt nicht ändert, und ist daher fehlerhaft. Jetzt hat C bereits ein schwaches Typsystem, in dem Sie eine Umwandlung eines Double in ein int neu interpretieren können, wenn Sie es wirklich wollen. Daher sollte es keine Überraschung sein, dass es auch in Bezug auf const ein schwaches Typsystem hat. Aber C # wurde entwickelt, um ein gutes Typsystem zu haben, ein Typsystem, bei dem, wenn Sie sagen "diese Variable enthält eine Zeichenfolge", die Variable tatsächlich einen Verweis auf eine Zeichenfolge (oder null) enthält. Wir wollen absolut keinen C-artigen "const" -Modifikator in das Typsystem einfügen, weil wir nicht wollen, dass das Typsystem eine Lüge ist . Wir möchten, dass das Typsystem stark ist, damit Sie Ihren Code richtig beurteilen können.
Const in C ist eine Richtlinie ; es bedeutet im Grunde "Sie können mir vertrauen, dass ich nicht versuche, dieses Ding zu mutieren". Das sollte nicht im Typensystem sein ; Das Zeug im Typsystem sollte eine Tatsache über das Objekt sein , über die Sie nachdenken können, und keine Richtlinie für seine Verwendung.
Versteh mich jetzt nicht falsch; Nur weil const in C tief gebrochen ist, heißt das nicht, dass das gesamte Konzept nutzlos ist. Was ich gerne sehen würde, ist eine tatsächlich korrekte und nützliche Form der "const" -Anmerkung in C #, eine Annotation, die sowohl Menschen als auch Compiler verwenden könnten, um ihnen das Verständnis des Codes zu erleichtern, und die die Laufzeit verwenden könnte, um Dinge wie automatische Paralellisierung und andere erweiterte Optimierungen.
Stellen Sie sich zum Beispiel vor, Sie könnten ein Kästchen um einen Codestück "zeichnen" und sagen "Ich garantiere, dass dieser Codestück keine Mutationen zu einem Feld dieser Klasse ausführt", auf eine 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". Ein solches 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 auf Code setzen 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 Feature in eine hypothetische zukünftige Version von C # zu integrieren, wenn 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 das die kommende Betonung des Multi-Core-Computing möglicherweise erfordert, aber nichts 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 Anmerkung zur lokalen Variablen wünschen, bei der es sich um einen Parameter handelt, der besagt, dass sich der Wert dieses Parameters während der gesamten Methode nicht ändert, ist dies natürlich problemlos möglich. Wir könnten "schreibgeschützte" Lokale und Parameter unterstützen, die einmal initialisiert werden, und einen Fehler bei der Kompilierung, der in der Methode geändert werden muss. Die von der Anweisung "using" deklarierte Variable ist bereits eine solche lokale Variable. Wir könnten allen Einheimischen und Parametern eine optionale Anmerkung hinzufügen, damit sie sich wie "using" -Variablen verhalten. Es war noch nie eine Funktion mit sehr hoher Priorität, daher wurde es nie implementiert.
quelle
0xDEADBEEF
. Aber beide wären sehr schlecht programmiert und würden von jedem modernen Compiler früh und ergreifend erfasst. Verwechseln Sie in Zukunft beim Schreiben von Antworten bitte nicht das, was technisch möglich ist, indem Sie die Hintertüren einer Sprache mit dem verwenden, was im tatsächlichen Code möglich ist. Solche verzerrten Informationen verwirren weniger erfahrene Leser und beeinträchtigen die Qualität der Informationen zu SO.Einer der Gründe, warum es in C # keine konstante Korrektheit gibt, ist, dass es auf Laufzeitebene nicht vorhanden ist. Denken Sie daran, dass C # 1.0 keine Funktion hatte, es sei denn, es war Teil der Laufzeit.
Und mehrere Gründe, warum die CLR keine Vorstellung von konstanter Korrektheit hat, sind zum Beispiel:
Const-Korrektheit ist so ziemlich eine Sprachfunktion, die nur in C ++ vorhanden ist. Es läuft also ziemlich genau auf die gleiche Argumentation hinaus, warum die CLR keine geprüften Ausnahmen erfordert (was eine reine Java-Sprachfunktion ist).
Ich glaube auch nicht, dass Sie eine so grundlegende Systemfunktion in einer verwalteten Umgebung einführen können, ohne die Abwärtskompatibilität zu beeinträchtigen. Verlassen Sie sich also nicht darauf, dass die Konstanz-Korrektheit jemals in die C # -Welt eintritt.
quelle
ref
Parameter schreiben darf / soll (insbesondere im Fall von Strukturmethoden / -eigenschaftenthis
). Wenn eine Methode ausdrücklich angibt, dass sie nicht in einenref
Parameter schreibt, sollte der Compiler die Übergabe schreibgeschützter Werte zulassen. Wenn umgekehrt eine Methode angibt, dass sie schreiben wirdthis
, sollte der Compiler nicht zulassen, dass eine solche Methode für schreibgeschützte Werte aufgerufen wird.Ich glaube, es gibt zwei Gründe, warum C # nicht konstant ist.
Das erste ist die Verständlichkeit . Nur wenige C ++ - Programmierer verstehen die Richtigkeit von Konstanten. Das einfache Beispiel von
const int arg
ist niedlich, aber ich habe auch gesehenchar * const * const arg
- einen konstanten Zeiger auf konstante Zeiger auf nicht konstante Zeichen. Die Konstanzkorrektur von Zeigern auf Funktionen ist eine völlig neue Ebene der Verschleierung.Das zweite ist, weil Klassenargumente Referenzen sind, die als Wert übergeben werden. Dies bedeutet, dass bereits zwei Ebenen der Konstanz ohne eine offensichtlich klare Syntax zu bewältigen sind . Ein ähnlicher Stolperpunkt sind Sammlungen (und Sammlungen von Sammlungen usw.).
Konstantenkorrektheit ist ein wichtiger Bestandteil des C ++ - Typsystems. Es könnte theoretisch zu C # als etwas hinzugefügt werden, das nur zur Kompilierungszeit überprüft wird (es muss nicht zur CLR hinzugefügt werden und würde die BCL nur beeinflussen, wenn der Begriff der const-Member-Methoden enthalten wäre). .
Ich halte dies jedoch für unwahrscheinlich: Der zweite Grund (Syntax) wäre ziemlich schwer zu lösen, was den ersten Grund (Verständlichkeit) noch problematischer machen würde.
quelle
modopt
undmodreq
auf Metadatenebene , dass Informationen zu speichern (wie C + / CLI bereits tut - sieheSystem.Runtime.CompilerServices.IsConst
); und dies könnte trivial auch auf const-Methoden ausgedehnt werden.const
bedeutet "Kompilierungszeitkonstante" in C #, nicht "schreibgeschützt, aber möglicherweise durch anderen Code veränderbar" wie in C ++. Ein grobes Analogon von C ++const
in C # istreadonly
, aber dieses gilt nur für Felder. Abgesehen davon gibt es in C # überhaupt keinen C ++ - ähnlichen Begriff der Konstantenkorrektheit.Die Begründung ist schwer zu sagen, da es viele mögliche Gründe gibt, aber ich vermute, dass ich die Sprache in erster Linie einfach halten möchte und unsichere Vorteile bei der Implementierung dieser zweiten.
quelle
Dies ist seit C # 7.2 (Dezember 2017 mit Visual Studio 2017 15.5) möglich.
Nur für Strukturen und Grundtypen ! , nicht für Klassenmitglieder.
Sie müssen verwenden
in
, um das Argument als Eingabe als Referenz zu senden. Sehen:Siehe: https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/in-parameter-modifier
Für Ihr Beispiel:
quelle