¿Cuál es la diferencia en estas formas de crear la instancia estática para un singleton?

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

  •  03-07-2019
  •  | 
  •  

Pregunta

Recientemente tuve un error que solo se manifestó cuando la biblioteca se creó como una versión de lanzamiento en lugar de una versión de depuración. La biblioteca es un .NET dll con un contenedor COM y estoy usando CoCreateInstance para crear una clase desde el dll en una aplicación c ++ no administrada. Cuando finalmente rastreé el error, fue causado por acceder a un objeto singleton. Tuve la instancia de singleton declarada así:

private static readonly MyObjectType s_instance = new MyObjectType;

y luego accedió con:

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

esto estaba fallando. Cambiándolo a:

private static MyObjectType s_instance;

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

solucionó el problema. ¿Alguna idea de por qué el uso inicial no funcionó y si existen inconvenientes para hacerlo de cualquier manera?

La dll de lanzamiento parecía ser perfectamente utilizable desde otra aplicación administrada.

¿Fue útil?

Solución

Intente agregar un constructor estático (vacío) o inicialice el singleton en un constructor estático.

Jon Skeet tiene una discusión completa sobre los patrones de singleton aquí . No estoy seguro de por qué falló, pero supongo que podría relacionarse con el " beforefieldinit " bandera. Vea su cuarto ejemplo, donde agrega un constructor estático para modificar esta bandera. No pretendo ser un experto en el campo anterior, pero este síntoma parece encajar en algunos de los síntomas analizados aquí .

Otros consejos

Solo reiterando lo que dijo Marc Gravell, pero suena mucho como un problema antes del campo, lo que significa que el constructor estático vacío es su solución. Necesitará publicar cualquiera y todos los constructores en la clase para obtener una respuesta definitiva.

El segundo método tiene la ventaja de la carga perezosa (donde eso es una ventaja).

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top