Quelle est la différence entre ces façons de créer l'instance statique d'un singleton?

StackOverflow https://stackoverflow.com/questions/217932

  •  03-07-2019
  •  | 
  •  

Question

J'ai récemment eu un bogue qui ne s'est manifesté que lorsque la bibliothèque a été construite sous la forme d'une version finale plutôt que d'une version de débogage. La bibliothèque est une dll .NET avec un wrapper COM et j'utilise CoCreateInstance pour créer une classe à partir de la dll dans une application c ++ non gérée. Quand j'ai finalement suivi le bogue, il était causé par l'accès à un objet singleton. J'ai eu l'instance singleton déclarée comme telle:

private static readonly MyObjectType s_instance = new MyObjectType;

et y a accédé avec:

public static MyObjectType Instance 
    { 
        get 
        {                               
            return s_instance; 
        } 
    } 

cela échouait. Le changer pour:

private static MyObjectType s_instance;

public static MyObjectType Instance 
    { 
        get 
        {               
            if (s_instance==null) 
            { 
                s_instance = new MyObjectType(); 
            } 
            return s_instance; 
        } 
    } 

résolu le problème. Des idées sur la raison pour laquelle l'utilisation initiale n'a pas fonctionné et s'il y a des inconvénients à le faire de toute façon?

La DLL de version semblait être parfaitement utilisable à partir d'une autre application gérée.

Était-ce utile?

La solution

Essayez d’ajouter un constructeur statique (vide) ou d’initialiser le singleton dans un constructeur statique.

Jon Skeet discute en détail des modèles de singleton ici . Je ne sais pas pourquoi cela a échoué, mais à un moment donné cela pourrait concerner le "beforefieldinit" drapeau. Voir son 4ème exemple, où il ajoute un constructeur statique pour peaufiner cet indicateur. Je ne prétends pas être un expert de beforefieldinit, mais ce symptôme semble correspondre à certains des symptômes discutés ici .

Autres conseils

Je répète juste ce que Marc Gravell a dit, mais cela ressemble beaucoup à un problème beforefieldinit, ce qui signifie que le constructeur statique vide est votre solution. Vous devez publier tous les constructeurs de la classe pour obtenir une réponse définitive.

La deuxième méthode présente l’avantage du chargement paresseux (c’est un avantage).

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top