Laden...

Durch Get-Accessor schreiben?

Erstellt von serial vor 16 Jahren Letzter Beitrag vor 16 Jahren 2.198 Views
S
serial Themenstarter:in
902 Beiträge seit 2007
vor 16 Jahren
Durch Get-Accessor schreiben?

Hallo,

ich habe gerade aus spaß bisschem gefrickelt, und wollte mal sehen was hier passiert...


class Program
    {
        static void Main(string[] args)
        {
            Tester t = new Tester();
            Console.WriteLine(t.Date.var);
            t.Date.var = 20;
            Console.WriteLine(t.Date.var);
        }
    }

    class Test
    {
        public int var;
    }

    class Tester
    {
        private Test t;
        public Tester()
        {
            t = new Test();
            t.var = 10;
        }

        public Test Date
        {
            get { return t; }
        }
    }
}

so, nun wird 10 und dann 20 angezeigt!
Aber wie kann ich das verhindern?
Ich möchte praktisch, das t nur readonly ist!

UÒder muss ich in der Klasse Test selbst an die sache rangehen?

49.485 Beiträge seit 2005
vor 16 Jahren

Hallo serial,

verwende keine öffentlichen Membervariablen. Fasse die Klasse Test und Tester zu einer Klasse zusammen.

herbivore

S
serial Themenstarter:in
902 Beiträge seit 2007
vor 16 Jahren

ja ich weiss schon!
Das sollte ja nur als Minimalbeispiel dienen!

Aber nehmen wir an, die klassen könnte ich nicht zusammenfassen, und Test wäre eben unumgänglich ein Member von Tester, und auf das Member darf von ausserhalb nur lesend zugegriffen werden!?

49.485 Beiträge seit 2005
vor 16 Jahren

Hallo serial,

wie schon gesagt, verwende keine öffentlichen Membervariablen. Verwende stattdessen Properties. Dann kannst du steuern, welche Zugriffe erlaubt sind.

herbivore

S
8.746 Beiträge seit 2005
vor 16 Jahren

Wenn t readonly sein soll, dann müssen eben ALLE Member von t readonly sein, und deren Member, und deren Member....

Und var ist es eben nicht.

Und wenn du jetzt sagst: "Ich will aber...", dann sage ich: "Geht nicht."

D
462 Beiträge seit 2005
vor 16 Jahren

Hallo!

Ich denke es geht serial eher darum, dass man das, durch das Get-Property erhaltene, Objekt verändern kann, auch wenn es nicht "ge-set-tet" werden kann.

@Serial: Durch ein Property ohne Set-Accessor ist lediglich der Verweis zum Objekt schreibgeschützt, nicht aber das (Ziel-)Objekt selbst (!).

mfg

49.485 Beiträge seit 2005
vor 16 Jahren

Hallo DeveloperX,

Ich denke es geht serial eher darum, dass man das, durch das Get-Property erhaltene, Objekt verändern kann, auch wenn es nicht "ge-set-tet" werden kann.

ah, ok, da könntest du wohl Recht haben.

Hallo serial,

wenn man das willst, könntest du einen ReadOnly-Wrapper zurückliefern ... dann du dann allerdings selbst schreiben müsstest. Zu Beispiel bei ArrayList gibt es sowas ArrayList.ReadOnly.

herbivore

S
8.746 Beiträge seit 2005
vor 16 Jahren

Ich denke, hier gehts um "deep immutable objects". Ähnelt im Prinzip dem const in C++. Gibts nicht in C#, wirds m.E. auch nicht geben. Entweder man macht das wie in C++ mit dem bekannten Problem, dass man Unmengen an Code duplizieren muss (das ist an sich nicht weiter schlimm, führt aber in die Wartungshölle), oder man braucht einen extrem schlauen Compiler (den ich bisher nicht gesehen hab und von dem ich glaube, dass er theoretisch nicht existieren kann), oder man löst es zur Laufzeit über die VM (so machen es einige Smalltalk-Implementierungen) via Attribute. Letzteres ist leider sehr performance-fressend.

Der große Nutzen von deep immutable objects in die 100%-ige Threadsicherheit solcher Objekte. Das übliche "damit der Nutzer aus Versehen nix verkehrt macht" ist völlig überbewertet und rechtfertigt nicht den obigen Aufwand. Ich persönlich kann mich nicht daran erinnern, jemals einen einzigen solcher Fehler begangen zu haben...

S
serial Themenstarter:in
902 Beiträge seit 2007
vor 16 Jahren

genau @Developer!

Aber wie ich sehe, ist das problem also nciht ganz trivial, mal schauen wie ich das mit dem wrapper hinbekomme, wobei ich ehrlich gesagt noch keine richtige vorstellung habe!
Ist wohl in der Art, das eine Klasse zurückgeliefert wird, die wiederum die properties etc von test kapselt, aber jeglichen zugriff darauf verweigert (sie hat selbst nur get properties)?!

49.485 Beiträge seit 2005
vor 16 Jahren

Hallo serial,

Ist wohl in der Art, das eine Klasse zurückgeliefert wird, die wiederum die properties etc von test kapselt, aber jeglichen zugriff darauf verweigert (sie hat selbst nur get properties)?!

Ja, das wäre eine Möglichkeit. Die Möglichkeit bei dem ArrayList-Beispiel ist, dass die Setter zwar da sind, aber eine Exception werfen, wenn man sie benutzt.

herbivore

S
serial Themenstarter:in
902 Beiträge seit 2007
vor 16 Jahren

ok, aber ist es da nicht besser, sie wegzulassen?
Da wird man ja gleich "aufmerksam" gemacht, wenn man sie ausversehen verwenden will, statt eine unschöne exception (vielleicht sogar erst zur laufzeit beim kunden)

49.485 Beiträge seit 2005
vor 16 Jahren

Hallo serial,

beide Lösungen haben vor und Nachteile. Den Vorteil des Weglassens hast du genannt. Der Vorteil der Exception-Lösung ist, dass die Schnittstelle von Wrapper und Original identisch ist. ArrayList.ReadOnly implementiert genauso IList wie ArrayList selbst und kann an allen Stellen verwendet und übergeben werden, wo eine ArrayList verwendet werden kann. Das ist also eine Abwägungsfrage.

herbivore