86 Stimmen

Gibt es eine Möglichkeit, eine Eigenschaft nur einmal in C# zu setzen

Ich bin auf der Suche nach einem Weg, um eine Eigenschaft in einem C#-Objekt zu ermöglichen, nur einmal festgelegt werden. Es ist einfach, den Code zu schreiben, um dies zu tun, aber ich würde lieber einen Standard-Mechanismus verwenden, wenn eine existiert.

public OneShot<int> SetOnceProperty { get; set; }

Was ich will, ist, dass die Eigenschaft festgelegt werden kann, wenn es nicht bereits festgelegt ist, aber eine Ausnahme auslösen, wenn es zuvor festgelegt wurde. Es sollte wie ein Nullable Wert funktionieren, wo ich überprüfen kann, ob es festgelegt wurde oder nicht.

0voto

VoteCoffee Punkte 3834

Die Antworten gehen davon aus, dass Objekte, die in der Zukunft einen Verweis auf ein Objekt erhalten, nicht versuchen werden, es zu ändern. Wenn Sie sich dagegen schützen wollen, müssen Sie dafür sorgen, dass Ihr Write-once-Code nur für Typen funktioniert, die ICloneable implementieren oder Primitive sind. Der Typ String implementiert beispielsweise ICloneable.

Generika nur für Primitive: T GetObject wobei T: struct;

Dies ist nicht erforderlich, wenn Sie wissen, dass Objekte, die einen Verweis auf die Daten erhalten, diese niemals überschreiben werden.

Überlegen Sie auch, ob die ReadOnlyCollection für Ihre Anwendung geeignet ist. Eine Ausnahme wird immer dann ausgelöst, wenn eine Änderung der Daten versucht wird.

0voto

StarFox Punkte 519

Während die akzeptierten und am besten bewerteten Antworten diese (ältere) Frage am direktesten beantworten, bestünde eine andere Strategie darin, eine Klassenhierarchie so aufzubauen, dass Sie Kinder über Eltern und die neuen Eigenschaften konstruieren können:

public class CreatedAtPointA 
{
    public int ExamplePropOne { get; }
    public bool ExamplePropTwo { get; }

    public CreatedAtPointA(int examplePropOne, bool examplePropTwo)
    {
        ExamplePropOne = examplePropOne;
        ExamplePropTwo = examplePropTwo;
    }
}

public class CreatedAtPointB : CreatedAtPointA
{
    public string ExamplePropThree { get; }

    public CreatedAtPointB(CreatedAtPointA dataFromPointA, string examplePropThree) 
        : base(dataFromPointA.ExamplePropOne, dataFromPointA.ExamplePropTwo)
    {
        ExamplePropThree = examplePropThree;
    }
}

Indem man sich auf Konstruktoren verlässt, kann man etwas Febreeze auf den Codegeruch sprühen, obwohl es immer noch mühsam und eine potenziell teure Strategie ist.

0voto

Pellet Punkte 2056

Ich habe einen Typ erstellt, bei dem ein Wert bei der Erstellung festgelegt werden kann, Danach kann der Wert nur noch einmal gesetzt/überschrieben werden, ansonsten wird eine Ausnahme ausgelöst.

public class SetOnce<T>
{
    bool set;
    T value;

    public SetOnce(T init) =>
        this.value = init;

    public T Value
    {
        get => this.value;
        set
        {
            if (this.set) throw new AlreadySetException($"Not permitted to override {this.Value}.");
            this.set = true;
            this.value = value;
        }
    }

    public static implicit operator T(SetOnce<T> setOnce) =>
        setOnce.value;

    class AlreadySetException : Exception
    {
        public AlreadySetException(string message) : base(message){}
    }
}

-2voto

ruslander Punkte 3729

Sie können dies tun, aber es ist keine klare Lösung und die Lesbarkeit des Codes ist nicht die beste. Wenn Sie sich mit Code-Design beschäftigen, können Sie einen Blick darauf werfen Einzelperson Realisierung in Verbindung mit AOP zur abfangen. Setzer. Die Realisierung ist nur 123 :)

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X