7 Stimmen

Frage zu nicht-statischen Mitgliedern eines Singletons (C#)

Ich habe eine Frage zu Singletons, von der ich denke, dass ich die Antwort darauf kenne... aber jedes Mal, wenn das Szenario auftaucht, habe ich irgendwie Zweifel an mir selbst, also würde ich gerne die konkrete Antwort wissen.

Sagen wir, ich habe zwei Klassen, die wie folgt eingerichtet sind...

 public class ClassA
 {
     private static ClassA _classA;

     public static ClassA Instance { get { return _classA ?? LoadClassA(); } }

     private ClassA(){}

     public static ClassA LoadClassA()
     {
         _classA = new ClassA();
         return _classA;
     }

     private ClassB _classB = new ClassB();

     public ClassB ClassB { get { return _classB; } set { _classB = value; } }
 }

 public class ClassB
 {
 }

Meine Frage ist einfach.

Ich frage mich, ob das Feld _classB auch als statisch behandelt wird, wenn ich auf das Singleton für ClassA zugreife? Auch wenn ich _classB nicht als statisches Mitglied deklariert habe.

Ich habe immer nur vermutet, dass _classB als statisch behandelt wird (ein Speicherplatz), aber ich würde es gerne genau wissen. Liege ich falsch? Wird für _classB jedes Mal ein neues Objekt erstellt, wenn man von der Singleton-KlasseA darauf zugreift, obwohl es nur eine KlasseA im Speicher gibt? Oder liegt es daran, dass ich _classB bei der Deklaration neu angelegt habe, was dazu führt, dass es nur eine Instanz von _classB gibt?

Vielen Dank im Voraus, -Matt

0voto

Justin Punkte 827

Warum kennzeichnen Sie nicht einfach KlasseB als statisch, wenn Sie nur eine Instanz benötigen?

Meiner Meinung nach ist es immer besser, einen klaren Code zu schreiben, aus dem alle Absichten hervorgehen. Auf diese Weise muss die nächste Person, die an Ihrem Code arbeitet, nicht raten, um herauszufinden, was Sie tun wollten.

0voto

NerdFury Punkte 18121

Da ClassA ein Singleton ist, gibt es nur eine Instanz davon in Ihrer Anwendung. Innerhalb dieser Klasseninstanz gibt es ein Mitglied, das eine ClassB-Variable speichert. Sobald Sie diese Variable initialisieren, ist sie eine Instanzvariable, aber da Sie nur eine Instanz von ClassA haben, werden Sie immer dieselbe Instanz von ClassB erhalten.

Außerdem würde ich von Ihrer Art der Erstellung der internen Instanz abraten, da sie nicht thread-sicher ist.

private static ClassA _instance = new ClassA();

private ClassA() {}

public static ClassA Insance { get { return _instance; } }

Indem Sie das Laden nicht verzögern und sofort initialisieren, gewährleisten Sie die Thread-Sicherheit.

0voto

Paul Sonier Punkte 37609

_classB ist nicht statisch; eine Instanz von ClassA enthält einen Verweis auf eine Instanz von _classB; wenn die Instanz von ClassA statisch ist (wie in der Singleton-Instanz), dann enthält sie immer noch einen Verweis auf _classB, aber neue Instanzen von ClassA enthalten UNTERSCHIEDLICHE Verweise auf (potenziell) verschiedene Instanzen von _classB. Wenn Sie also auf dieselbe Instanz von ClassA verweisen (durch das Singleton-Pattern), erhalten Sie immer noch dieselbe Instanz von _classB; wenn Sie jedoch eine neue Instanz von ClassA erstellen, erhalten Sie eine andere Instanz von _classB, weshalb _classB nicht statisch ist.

0voto

Ich bin erstaunt, dass niemand auf die Tatsache hingewiesen hat, dass ClassB ist eine öffentliche Eigenschaft von ClassA mit einem öffentlichen Setter. Als solches hält nichts jemanden davon ab, etwas wie zu schreiben:

ClassA.Instance.ClassB = new ClassB();

Dies würde die Instanz von ClassB erstellt zu der Zeit ClassA erstellt wurde und diese durch die neu erstellte Instanz von ClassB .

Ein ähnliches Szenario ist, dass, solange _classB in einer abgeleiteten Klasse setzbar ist (z. B. wenn der Setter für ClassB geschützt wurde), kann nicht garantiert werden, dass es nur einen einzigen Fall von ClassB jemals.

Ich nehme an, der korrekte Weg, diese Art von Code zu schreiben, wäre die Implementierung beider ClassA y ClassB als Singletons und machen ClassB eine innere Klasse von ClassA (sonst hätte man 2 nicht zusammenhängende Klassen ClassA y ClassB mit einem Verweis auf ClassB erhältlich über ClassA.Instance.ClassB was (in diesem Szenario) nicht anders wäre als ClassB.Instance .

Si ClassB war nur instanzierbar innerhalb von ClassA dann könnte es möglicherweise andere Fälle von ClassB in einer abgeleiteten Klasse instanzierbar.

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