Laden...

private field anderer Instanz derselben Klasse kann gesetzt werden; ist das korrekt?

Erstellt von inflames2k vor 13 Jahren Letzter Beitrag vor 13 Jahren 1.047 Views
inflames2k Themenstarter:in
2.298 Beiträge seit 2010
vor 13 Jahren
private field anderer Instanz derselben Klasse kann gesetzt werden; ist das korrekt?

Hallo,

ich habe gerade ein merkwürdiges Verhalten entdeckt. Und zwar ist es folgendes. Ich habe eine Klasse, welche mehrere Private Properties beinhaltet.

Nun nutze ich innerhalb dieser Klasse in einer Methode auch eine Instanz dieser Klasse.

Das verhalten was ich nun beschreiben möchte ist, dass ich dem Private field einen Wert zuweisen kann.

Um es genauer aufzuzeigen hier mal der Quelltext:


class ConfigurationBase
{
       private bool _bLoaded;
       public bool Loaded
       {
            get { return _bLoaded; }
       }

       private ConfigurationBase Load()
       {
            ConfigurationBase config = null;
            XmlSerializer serializer = new XmlSerializer(this.GetType());
            Stream stream = null;

            try
            {
                if (File.Exists(_sConfigFile))
                {
                    stream = File.Open(_sConfigFile, FileMode.Open);
                    config = (ConfigurationBase)serializer.Deserialize(stream);
                    this._bLoaded = true;
                }
            }
            catch
            {
                this._bLoaded = false;
            }
            finally
            {
                if (stream != null)
                    stream.Close();               
            }

            // hier greife ich auf den Private member zu???
            // dürfte doch eigentlich nicht sein.
            config._bLoaded = _bLoaded;
            return config;
       }
}

Man kann gut erkennen, dass ich am Ende der Methode Load() auf den Private Member zugreife. - Ist dies ein Fehler im Framework? Denn ich kann mir nicht vorstellen, dass ich diese so einfach setzen kann. - Schließlich ist diese ja private und ich greife von Extern auf das Field zu.

Kennt jemand eventuell schon dieses Verhalten?

Wenn es kein Fehler sein sollte, warum kann hier auf ein private Field geschrieben werden?

Wissen ist nicht alles. Man muss es auch anwenden können.

PS Fritz!Box API - TR-064 Schnittstelle | PS EventLogManager |

S
417 Beiträge seit 2008
vor 13 Jahren

Hallo,

was du beschreibst ist kein bug, sondern ein korrektes Verhalten des private-Modifiers.
Private bedeutet, dass das jeweilige Element (Feld, Methode etc.) nur innerhalb der jeweiligen Klasse sichtbar ist. Und genau das ist bei dir der Fall.
Innerhalb der Load-Methode befindest du dich in der Klasse ConfigurationBase und kannst daher auch auf deren private Elemente zugreifen, in deinem Fall auf das Feld _bLoaded.

inflames2k Themenstarter:in
2.298 Beiträge seit 2010
vor 13 Jahren

Die Sache ist doch aber, dass config in dem Fall eine konkrete Instanz ist. - Und meines Verständnis nach, dürfte ich auch wenn ich mich in einer Klasse selben Typs befinde keinen Zugriff darauf haben.

Dass ich innerhalb der Klasse in der ich die Load Methode ausführe _bLoaded dieser Instanz setzen kann ist mir klar. - Jedoch ist doch wie gesagt "config" nicht die Instanz selbst sondern eine neue gleichen Typs.

Ich meine, es kann auch sein dass mein Verständnis falsch ist, aber:

Auch wenn ich am Motor meines Autos Änderungen vornehme, kann ich noch lang nicht die Zündkerzen deines Autos austauschen. - Aber vom Prinzip her tue ich hier doch genau das.

Wissen ist nicht alles. Man muss es auch anwenden können.

PS Fritz!Box API - TR-064 Schnittstelle | PS EventLogManager |

S
417 Beiträge seit 2008
vor 13 Jahren

Die Sache ist doch aber, dass config in dem Fall eine konkrete Instanz ist.

Das spielt für den private-Modifier keine Rolle. Das Verhalten ist schon korrekt so wie es ist und hat für diverse Szenarien auch ihren Sinn.
Denke beispielsweise an ein Szenario in dem du den Konstruktor einer Klasse private machst, da du die Instanzierung von außerhalb verbieten möchtest (z.B. beim Singleton-Pattern, wobei ich kein Fan davon bin).
Könntest du dann in einer statischen Methode ebenfalls nicht auf den Konstruktor zugreifen, dann hättest du selbst keine Chance ein Objekt dieser Klasse zu erzeugen.

Beispiel:


public class Dummy
{
	private Dummy()
	{}
	
	public static Dummy CreateDummy()
	{
		return new Dummy(); // wäre nicht möglich wenn es nach dir ginge :)
	}
}
1.002 Beiträge seit 2007
vor 13 Jahren

Hallo inflames2k,

Und meines Verständnis nach, dürfte ich auch wenn ich mich in einer Klasse selben Typs befinde keinen Zugriff darauf haben.

genau so ist es aber. Das ist kein Fehlverhalten, sondern korrekt.
Hier der entsprechende Auszug aus Access Modifiers (C# Programming Guide):

private

The type or member can be accessed only by code in the same class or struct.

m0rius

Mein Blog: blog.mariusschulz.com
Hochwertige Malerarbeiten in Magdeburg und Umgebung: M'Decor, Ihr Maler für Magdeburg

inflames2k Themenstarter:in
2.298 Beiträge seit 2010
vor 13 Jahren

Ok, das ist ein Argument dass ich außer Acht gelassen hatte. Unter dem Gesichtspunkt habe ich nun falsch gelegen.

Aber merkwürdig fand ichs dennoch. Und ich kann mir auch nicht vorstellen, dass die Verwendung (außer beim Singleton) gutes Design wäre.

Merkwürdig auch dass ich das immer überlesen habe & mir das Verhalten nie auffiel.

Aber da weis ich nun ersteinmal bescheid.

Wissen ist nicht alles. Man muss es auch anwenden können.

PS Fritz!Box API - TR-064 Schnittstelle | PS EventLogManager |

6.911 Beiträge seit 2009
vor 13 Jahren

Hallo,

noch als Ergänzung. In einer nested Class kann auch auf die privaten Felder der Container Class zuzugriffen werden.


class Program
{
	static void Main(string[] args)
	{
		Foo foo = new Foo();
		Foo.Boo boo = new Foo.Boo(foo);

		// foo._privateFieldOfFoo ist nun korrekt gesetzt.
	}
}

public class Foo
{
	private object _privateFieldOfFoo;

	public class Boo
	{
		private Foo _foo;

		public Boo(Foo foo)
		{
			_foo = foo;

			_foo._privateFieldOfFoo = new object();
		}
	}
}

Ist für den Benutzercode zwar eher eine Ausnahme, aber der Compiler vewendest dieses Vorgehen oft bei CompilerGenerated (also Iteratoren, anonyme Methoden usw.)

mfG Gü

Stellt fachliche Fragen bitte im Forum, damit von den Antworten alle profitieren. Daher beantworte ich solche Fragen nicht per PM.

"Alle sagten, das geht nicht! Dann kam einer, der wusste das nicht - und hat's gemacht!"

49.485 Beiträge seit 2005
vor 13 Jahren

Hallo inflames2k,

die Klasse ist halt der Bauplan aller Objekte. Es ist weder ein Verstoß gegen OOP, noch gegen gutes Design, noch in anderer Weise schädlich, wenn man auf private Member einer anderen Instanz derselben Klasse zugreift. Als Autor der Klasse kennt man ja den inneren Aufbau aller Instanzen der Klasse, nicht nur der Instanz, auf die sich this bezieht. Beim Vergleichen (und auch beim Kopieren) von Objekten ist es ganz normal, auf die privaten Member aller beteiligten Instanzen zuzugreifen.

herbivore