Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 | Suche | FAQ

Hauptmenü
myCSharp.de
» Startseite
» Forum
» Suche
» Regeln
» Wie poste ich richtig?

Mitglieder
» Liste / Suche
» Wer ist online?

Ressourcen
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Microsoft Docs

Team
» Kontakt
» Cookies
» Spenden
» Datenschutz
» Impressum

private field anderer Instanz derselben Klasse kann gesetzt werden; ist das korrekt?
inflames2k
myCSharp.de - Experte

Avatar #AARsmmPEUMee0tQa2JoB.png


Dabei seit:
Beiträge: 2351

Themenstarter:

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

beantworten | zitieren | melden

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 | Spielkartenbibliothek
private Nachricht | Beiträge des Benutzers
Sarc
myCSharp.de - Member



Dabei seit:
Beiträge: 426

beantworten | zitieren | melden

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.
private Nachricht | Beiträge des Benutzers
inflames2k
myCSharp.de - Experte

Avatar #AARsmmPEUMee0tQa2JoB.png


Dabei seit:
Beiträge: 2351

Themenstarter:

beantworten | zitieren | melden

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 | Spielkartenbibliothek
private Nachricht | Beiträge des Benutzers
Sarc
myCSharp.de - Member



Dabei seit:
Beiträge: 426

beantworten | zitieren | melden

Zitat von inflames2k
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 :)
	}
}
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von Sarc am .
private Nachricht | Beiträge des Benutzers
m0rius
myCSharp.de - Member

Avatar #avatar-3125.png


Dabei seit:
Beiträge: 1043

beantworten | zitieren | melden

Hallo inflames2k,
Zitat von 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):
Zitat von 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
private Nachricht | Beiträge des Benutzers
inflames2k
myCSharp.de - Experte

Avatar #AARsmmPEUMee0tQa2JoB.png


Dabei seit:
Beiträge: 2351

Themenstarter:

beantworten | zitieren | melden

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.
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von inflames2k am .
Wissen ist nicht alles. Man muss es auch anwenden können.

PS Fritz!Box API - TR-064 Schnittstelle | PS EventLogManager | Spielkartenbibliothek
private Nachricht | Beiträge des Benutzers
gfoidl
myCSharp.de - Team

Avatar #avatar-2894.jpg


Dabei seit:
Beiträge: 7547
Herkunft: Waidring

beantworten | zitieren | melden

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!"
private Nachricht | Beiträge des Benutzers
herbivore
myCSharp.de - Experte

Avatar #avatar-2627.gif


Dabei seit:
Beiträge: 52329
Herkunft: Berlin

beantworten | zitieren | melden

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
private Nachricht | Beiträge des Benutzers