Qual é a diferença entre esses modos de criar a instância estática para um singleton?

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

  •  03-07-2019
  •  | 
  •  

Pergunta

Eu tive um bug recentemente que só se manifesta quando a biblioteca foi construída como uma compilação de lançamento, em vez de uma compilação de depuração. A biblioteca é um .NET dll com uma COM invólucro e estou usando CoCreateInstance para criar uma classe da DLL em um aplicativo não gerenciado c ++. Quando eu finalmente rastreou o bug para baixo ele foi causado por acessar um objeto singleton. Eu tinha a instância singleton declarada assim:

private static readonly MyObjectType s_instance = new MyObjectType;

e, em seguida, acessada com:

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

este estava falhando. Mudá-lo para:

private static MyObjectType s_instance;

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

corrigiu o problema. Alguma idéia por que o uso inicial não funcionou e se existem quaisquer desvantagens para fazê-lo de qualquer forma?

A dll liberação parecia ser perfeitamente utilizável a partir de outro aplicativo gerenciado.

Foi útil?

Solução

Tente adicionar um construtor estático (vazio), ou inicializar a Singleton em um construtor estático.

Jon Skeet tem uma discussão completa de padrões únicos aqui . Eu não sei por que ele falhou, mas a um palpite poderia relacionar com a bandeira "beforefieldinit". Veja seu quarto exemplo, onde ele adiciona um construtor estático para ajustar esta bandeira. Não tenho a pretensão de ser um especialista em beforefieldinit, mas este sintoma parece se encaixar alguns dos sintomas discutidos aqui .

Outras dicas

Apenas reiterando o que Marc Gravell disse, mas soa muito como um problema beforefieldinit, o que significa que o construtor estático vazio é a sua solução. Você precisaria para postar qualquer e todos os construtores na classe para obter uma resposta definitiva.

O segundo método tem a vantagem do carregamento lento (onde que é uma vantagem).

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top