Qual è la differenza in questi modi di creare l'istanza statica per un singleton?

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

  •  03-07-2019
  •  | 
  •  

Domanda

Di recente ho riscontrato un bug che si è manifestato solo quando la libreria è stata creata come build di rilascio piuttosto che come build di debug. La libreria è una dll .NET con un wrapper COM e sto usando CoCreateInstance per creare una classe dalla dll in un'app c ++ non gestita. Quando finalmente ho rintracciato il bug, è stato causato dall'accesso a un oggetto singleton. Ho avuto l'istanza singleton dichiarata così:

private static readonly MyObjectType s_instance = new MyObjectType;

e quindi accedervi con:

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

questo non stava funzionando. Modificandolo in:

private static MyObjectType s_instance;

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

risolto il problema. Qualche idea sul perché l'uso iniziale non ha funzionato e se ci sono degli svantaggi in entrambi i modi?

La release dll sembrava essere perfettamente utilizzabile da un'altra app gestita.

È stato utile?

Soluzione

Prova ad aggiungere un costruttore (vuoto) statico o inizializza il singleton in un costruttore statico.

Jon Skeet ha una discussione completa degli schemi singleton qui . Non sono sicuro del motivo per cui ha fallito, ma a quanto si suppone potrebbe essere correlato al "pre-fieldinit" bandiera. Guarda il suo quarto esempio, dove aggiunge un costruttore statico per modificare questa bandiera. Non pretendo di essere un esperto di beforefieldinit, ma questo sintomo sembra corrispondere ad alcuni dei sintomi discussi qui .

Altri suggerimenti

Ribadendo solo quello che ha detto Marc Gravell, ma suona molto come un problema pre-campo, il che significa che il costruttore statico vuoto è la tua soluzione. Dovresti pubblicare tutti i costruttori della classe per ottenere una risposta definitiva.

Il secondo metodo ha il vantaggio del caricamento lento (dove questo è un vantaggio).

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top