Der Punkt der Konstantenkorrektheit besteht darin, eine Ansicht einer Instanz bereitstellen zu können, die vom Benutzer nicht geändert oder gelöscht werden kann. Der Compiler unterstützt dies, indem er darauf hinweist, wenn Sie die Konstanz innerhalb einer const-Funktion aufheben oder versuchen, eine Nicht-const-Funktion eines const-Objekts zu verwenden. Gibt es eine Methode, die ich in C # verwenden kann, ohne den const-Ansatz zu kopieren, die dieselben Ziele hat?
Ich bin mir der Unveränderlichkeit bewusst, aber das überträgt sich nicht wirklich auf Containerobjekte, um nur ein Beispiel zu nennen.
c#
theory
const-correctness
Tenpn
quelle
quelle
const_cast
in C #?Antworten:
Ich bin auch oft auf dieses Problem gestoßen und habe Schnittstellen verwendet.
Ich denke, es ist wichtig, die Idee fallen zu lassen, dass C # irgendeine Form oder sogar eine Weiterentwicklung von C ++ ist. Es sind zwei verschiedene Sprachen, die fast dieselbe Syntax haben.
Normalerweise drücke ich 'const-Korrektheit' in C # aus, indem ich eine schreibgeschützte Ansicht einer Klasse definiere:
public interface IReadOnlyCustomer { String Name { get; } int Age { get; } } public class Customer : IReadOnlyCustomer { private string m_name; private int m_age; public string Name { get { return m_name; } set { m_name = value; } } public int Age { get { return m_age; } set { m_age = value; } } }
quelle
const
, ohne die zusätzlichen Kosten für die Definition einer separaten Schnittstelle und die Notwendigkeit eines Laufzeitversands. Das heißt, die Sprache bietet eine einfache Möglichkeit, const-Schnittstellen zur Kompilierungszeit zu implementieren.const
-ness ist Teil des Entwurfs und es erklärt die Absicht , ebenso klar wie eine externe const-Schnittstelle writting. Das Bereitstellen von const-Schnittstellen kann auch eine komplexe Aufgabe sein, wenn es manuell angegangen werden muss, und erfordert möglicherweise das Schreiben von fast so vielen Schnittstellen, wie Klassen im zusammengesetzten Typ vorhanden sind. Das bringt uns zu Ihrem letzten Satz: "Versauen Sie Dinge, weil Sie vergessen haben, die Konstante hinzuzufügen". Es ist einfacher, sich daran zu gewöhnen, dasconst
Überall hinzuzufügen (die Entwicklungskosten sind gering), als schreibgeschützte Schnittstellen für jede Klasse zu schreiben.Um den Vorteil der Konstanz (oder Reinheit in Bezug auf die funktionale Programmierung) zu nutzen, müssen Sie Ihre Klassen so gestalten, dass sie unveränderlich sind, genau wie die String-Klasse von c #.
Dieser Ansatz ist weitaus besser, als nur ein Objekt als schreibgeschützt zu markieren, da Sie mit unveränderlichen Klassen Daten in Multitasking-Umgebungen problemlos weitergeben können.
quelle
Builder
Klassen für große unveränderliche Typen (Java und .NET definieren dieStringBuilder
Klasse, die nur ein Beispiel ist).Ich wollte Ihnen nur mitteilen, dass viele der System.Collections.Generics-Container über eine AsReadOnly-Methode verfügen, mit der Sie eine unveränderliche Sammlung zurückerhalten.
quelle
C # hat keine solche Funktion. Sie können Argumente als Wert oder als Referenz übergeben. Die Referenz selbst ist unveränderlich, es sei denn, Sie geben den Modifikator ref an . Referenzierte Daten sind jedoch nicht unveränderlich. Sie müssen also vorsichtig sein, wenn Sie Nebenwirkungen vermeiden möchten.
MSDN:
Parameter übergeben
quelle
Schnittstellen sind die Antwort und tatsächlich leistungsfähiger als "const" in C ++. const ist eine einheitliche Lösung für das Problem, bei dem "const" definiert ist als "setzt keine Mitglieder oder ruft etwas auf, das Mitglieder setzt". Das ist in vielen Szenarien eine gute Abkürzung für Konstanz, aber nicht in allen. Stellen Sie sich beispielsweise eine Funktion vor, die einen Wert basierend auf einigen Elementen berechnet, aber auch die Ergebnisse zwischenspeichert. In C ++ wird dies als Nicht-Konstante betrachtet, obwohl es aus Sicht des Benutzers im Wesentlichen Konstante ist.
Schnittstellen bieten Ihnen mehr Flexibilität bei der Definition der spezifischen Teilmenge der Funktionen, die Sie von Ihrer Klasse bereitstellen möchten. Willst du Konstanz? Stellen Sie einfach eine Schnittstelle ohne Mutationsmethoden bereit. Möchten Sie zulassen, dass einige Dinge eingestellt werden, andere jedoch nicht? Stellen Sie eine Schnittstelle mit genau diesen Methoden bereit.
quelle
mutable
.Stimmen Sie einigen anderen zu, indem Sie schreibgeschützte Felder verwenden, die Sie im Konstruktor initialisieren, um unveränderliche Objekte zu erstellen.
public class Customer { private readonly string m_name; private readonly int m_age; public Customer(string name, int age) { m_name = name; m_age = age; } public string Name { get { return m_name; } } public int Age { get { return m_age; } } }
Alternativ können Sie auch Zugriffsbereich für die Eigenschaften hinzufügen, z. B. public get und protected set?
public class Customer { private string m_name; private int m_age; protected Customer() {} public Customer(string name, int age) { m_name = name; m_age = age; } public string Name { get { return m_name; } protected set { m_name = value; } } public int Age { get { return m_age; } protected set { m_age = value; } } }
quelle
Das Problem mit readonly ist, dass nur die Referenz (Zeiger) konstant sein kann. Das Objekt, auf das verwiesen wird (auf das verwiesen wird), kann noch geändert werden. Dies ist der schwierige Teil, aber es führt kein Weg daran vorbei. Um konstante Objekte zu implementieren, müssen sie keine veränderlichen Methoden oder Eigenschaften verfügbar machen. Dies ist jedoch umständlich.
Siehe auch Effektives C #: 50 spezifische Möglichkeiten zur Verbesserung Ihres C # (Punkt 2 - Lesen Sie lieber nur const.)
quelle