Frage

Wie kann ich herausfinden, ob eine Klasse in C # unveränderlich ist?

War es hilfreich?

Lösung

Es ImmutableObjectAttribute ist, aber dies wird selten verwendet und schlecht unterstützt -. Und natürlich nicht erzwungen (Sie könnten ein veränderbares Objekt mit [ImmutableObject(true)] markieren AFAIK, das einzige, was dies betrifft dies ist die Art und Weise der IDE Attribute behandelt (dh zu zeigen, die genannten Eigenschaften Optionen / nicht zeigen).

In der Realität würden Sie die FieldInfo.IsInitOnly überprüfen müssen, aber dies gilt nur dann wirklich 100% unveränderliche Typen (vorausgesetzt, keine Reflexion Missbrauch, usw.); es hilft nicht, mit Eis am Stiel Unveränderlichkeit, noch Dinge, die in der Praxis unveränderlich sind, aber nicht in ihrer Umsetzung; das heißt, sie können nicht öffentlich wandelbar sein werden gemacht, aber das Objekt unterstützt es in der Theorie.

Ein klassisches Beispiel hier String sein würde ... jeder „weiß“, dass string unveränderlich ist ... natürlich StringBuilder hat einen String unter der Motorhaube mutieren. Nein, im Ernst ...

Es ist so schwer Unveränderlichkeit gegeben, dies zu definieren, geschweige denn robust erkennt es ...

Andere Tipps

Sie können nicht, können Sie nur raten. Wenn alle Felder nur lesbar die Instanzen sind, werden unveränderlich sein, wenn der Konstruktor beendet. Dies ist wichtig, wenn Sie hatte die folgenden es wandelbar zum Beispiel bar erscheinen würde.

class Foo
{
    public readonly int X
    public readonly int Y
    public Foo(int x, int y, Bar bar)
    {
        this.X = x; 
        bar.ShowYourself(this);
        this.Y = y;
        bar.ShowYourself(this);
    }
}

Allerdings, wenn ein Feld auf dem angeblich unveränderlichen Klasse war eine Sammlung (und wurde nicht nur lesen), dann die Klasse aufrufen unveränderlich wahrscheinlich falsch sein würde (da es Staat kann sich ändern)

Hinweis

, dass selbst wenn alle Felder Nur-Lese-Reflexion sind erlaubt, die Felder zu ändern.

Überprüfen auf keinen Setter auf Eigenschaften wird in der Tat eine sehr schlechte Heuristik sein.

Ein Teil des Problems ist, dass „unveränderlich“ mehrere Bedeutungen haben kann. Nehmen wir zum Beispiel, Readonlycollection .

Wir neigen dazu, es zu prüfen, unveränderlich sein. Aber was, wenn es ein Readonlycollection ? Auch, weil es ist wirklich nur ein Wrapper um eine IList ich an den Konstruktor in, was ist, wenn ich das Original IList ändern?

Ein guter Ansatz könnte sein, ein Attribut mit einem Namen wie ReadOnlyAttribute zu erstellen und markieren Klassen, die Sie betrachten schreibgeschützt werden mit ihm. Für Klassen, die Sie nicht steuern, können Sie auch eine Liste der bekannten Typen halten, die Sie als unveränderlich sein.

EDIT: Für einige gute Beispiele für verschiedene Arten von Unveränderlichkeit, lesen Sie diese Reihe von Nachrichten von Eric Lippert: http://blogs.msdn.com/ericlippert/archive/2007/11/13/immutability-in-c- Teil-one-Art-of-immutability.aspx

Mein Wissen, es sei denn es ausdrücklich dokumentiert ist, gibt es keine Möglichkeit zu bestimmen, ob eine Klasse unveränderlich ist oder nicht in C #.

Sie können jedoch verwenden Reflexion für die Existenz von Setters auf Eigenschaften zu überprüfen; aber Mangel an Setter nicht garantieren Unveränderlichkeit als interner Zustand die Werte dieser Eigenschaften ändern kann, ob Sie explizit festlegen können oder nicht.

Zusätzlich wird für die ‚IsInitOnly‘ Flag Prüfung für die Felder der alle Klasse, wieder Reflexion verwendet wird, könnte Unveränderlichkeit zeigen, aber es ist es nicht garantieren.

Edit: Hier ist eine ähnliche Frage , fragte in Bezug auf die Java-Sprache, deren Antwort auch hier gilt.

Via Code, ich bin nicht sicher, aber afaik wenn man sich die IL eines anderen unveränderlichen Art aussehen, wie eine Zeichenfolge, die Sie werden nicht sehen eine newobj IL Anweisung (Sie werden sehen, ldstr vielleicht für Streicher), kann die IL der Schöpfung inspizieren eine Art und Weise zu sagen, nur eine Vermutung ...

Die einzige Hilfe, die Sie von der Laufzeit erhalten ist, wenn alle Felder in der Klasse mit Anmerkungen versehen werden mit „Nur-Lesen“. [Bearbeiten, siehe @ShuggyCoUk] Und selbst dann wird die CLR können Sie über sie schreiben. Ich überprüfte es einfach. Ugh.

Sie können die Objekte Fieldinfo aus der Klasse über Reflexion erhalten und prüfen IsInitOnly.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top