J'ai une question sur les singletons que je pense connaître la réponse à ... mais chaque fois que le scénario apparaît, je suis un peu d'autre que je devais moi-même donc je voudrais connaître la réponse concrète.
dis avoir deux classes configuration comme si ... p> Ma question est simple. P> Je me demande si le champ _Classb est traité comme statique aussi si j'accumule le singleton pour CLASSA? Même si je n'ai pas déclaré _Classb en tant que membre statique. P> J'ai toujours essentiellement deviné que _Classb il est traité comme statique (un emplacement de mémoire), mais j'aimerais savoir avec certitude. Ai-je tort? Est un nouvel objet créé pour _Classb chaque fois que vous y accédez de Singleton Classa ... Même s'il n'y a qu'une seule classe en mémoire? Ou est-ce parce que je me suis retrouvé sur la Déclaration qui lui causera une seule instance? P> Merci d'avance,
-Matt p> p>
9 Réponses :
_Classb est un membre d'instance (non statique) de CLASSA. Chaque instance de Classa aura une instance de _Classb (étant donné l'initialisateur de champ que vous avez écrit). Donc, si vous utilisez le schéma singleton pour accéder à CLASSA, et donc toujours avoir (au plus) une instance de CLASSA chargé, vous aurez toujours (au maximum) une instance de Classb chargée à titre de classe de classe.
Maintenant, puisque Classb dispose d'un constructeur par défaut public, quelque chose d'autre au loin pourrait créer des instances. Si c'est une préoccupation, envisagez de faire de la classe de classe de classe privée. De plus, comme CLASSA a un constructeur public par défaut, rien n'empêche les gens de créer autant d'instances que nécessaire. Vous pourriez faire le constructeur de no-arg Private: p>
tel que défini de la classe viole la définition du singleton. Imaginez deux threads en même temps appeler la propriété d'instance statique. Comme l'accès n'est pas synchronisé, vous pouvez obtenir avec deux instances différentes de Classa et donc deux instances différentes de Classb. P>
Je ne suis pas sûr que cela "violent la définition", comme dans une seule application filetée, tout irait bien. Mais il y a des problèmes de sécurité de fil que vous avez souligné.
Le modèle singleton garantit qu'une seule instance de Notez cependant que la portée de em> de classb code> est accessible de l'instance singleton de
classa code> em> à tout moment. L'ensemble du point du singleton est que garantit qu'une seule instance em> de
classa code> est disponible à tout moment, une seule référence à
_classb code> ( Bien que depuis
classa code> est mutable, cette référence peut changer). P>
classb code> est toujours au niveau de l'instance et non de niveau statique. Le compilateur sera jamais em> faire quelque chose d'aussi étrange pour utiliser un spécificateur de portée différent de celui que vous indiquez. Vous devez toujours accéder à la référence à
classb code> via une instance, que vous utilisiez ou non un singleton. P>
Lorsque vous créez un singleton, vous créez une seule instance statique d'un type non statique. P>
Dans ce cas, votre type (classe A) contient une référence à un autre type (classe B). L'instance statique tiendra une seule référence à une seule instance d'un objet de classe B. Techniquement, ce n'est pas "statique", mais comme il est enraciné à un objet statique (l'instance de classe A), elle se comportera comme une variable statique. Vous aurez toujours un seul et un seul objet de classe B (pointé par votre classe d'une classe A). Vous ne créerez jamais plus d'une classe B de classe B Il n'y a cependant rien, cependant, empêchant une instance B de deuxième classe B d'être générée ailleurs - ce serait un exemple différent. P>
Sauf si je vois quelque chose de mal ici, vous devez également créer un constructeur privé pour classa code>. Si vous ne le faites pas, il n'y aura plus rien d'empêcher le code extérieur de créer une nouvelle instance de
classa code>, ce qui signifie plus d'instances de
classb code> (comme chaque
CLASSA code> aura des copies indépendantes).
Cela m'a également dérangé, mais je pensais que ce n'est que parce que c'est environ 2 am :)
En ayant votre déclaration comme celle-ci:
private ClassB _classB = new ClassB();
Pourquoi ne pas simplement marquer Classb comme statique si vous ne voulez que une instance. P>
À mon avis, il est toujours préférable d'écrire un code clair qui vous montrent des intentions complètes. De cette façon, la personne suivante de travailler sur votre code n'a pas à jouer à un jeu de deviner pour déterminer ce que vous vouliez faire. P>
Marquage d'une classe comme statique empêche d'instancier des instances de cette classe. Clairement, des cas de classe et de classb sont nécessaires.
Parce que Classa est un singleton, il n'y en a qu'un exemple dans votre application. À l'intérieur de cette instance de classe, il y a un membre à stocker une variable de classe de classe. Une fois que vous initialisez cette variable, il s'agit d'une variable d'instance, mais puisque vous n'avez que 1 instance de CLASSA, vous obtiendrez toujours le même exemple de classb.
Je recommanderais également de la manière de créer l'instance interne telle qu'elle n'est pas Safe Safe. P>
private static ClassA _instance = new ClassA(); private ClassA() {} public static ClassA Insance { get { return _instance; } }
_Classb n'est pas statique; Une instance de CLASSA contient une référence à une instance de _Classb; Si l'instance de Classa est statique (comme dans l'instance Singleton), elle contiendra toujours une référence à _Classb, mais de nouvelles instances de CLASSA contiendront différentes références à (potentiellement) différentes instances de _Classb. Donc, si vous vous référez à la même instance de CLASSA (via le modèle Singleton), vous obtiendrez toujours le même exemple de _Classb; Mais si vous créez une nouvelle instance de CLASSA, vous obtiendrez un exemple différent de _Classb, c'est pourquoi _Classb n'est pas statique. P>
Je suis surpris que personne n'a signalé le fait que classb code> est une propriété publique de
classa code> avec un ensemble public. En tant que tel, rien n'arrête quiconque d'écrire quelque chose comme:
ClassA.Instance.ClassB = new ClassB();
Il y aura certainement une instance de _Classb.