Pregunta

Actualización para futuros lectores: Cuando salga .NET 4, LazyInit < T > del CTP habrá cambiado de nombre a Lazy < T > y se cambiará de una estructura a una clase, por lo que se aplicará muy poco de esto, excepto como una ilustración de por qué las estructuras mutables pueden ser problemáticas si no tienes cuidado.

He estado experimentando con LazyInit en el CTP de junio de Parallel Extensions, y esperaría que el siguiente código imprima el mismo Guid miles de veces, pero imprime mil Guías diferentes. Claramente, me falta algo obvio aquí acerca de cómo se supone que funciona LazyInit, y agradecería si alguien quisiera señalar qué es.

using System;
using System.Diagnostics;
using System.Threading;

namespace TestApp
{
    class Program
    {
        static void Main(string[] args)
        {
            for (int i=0; i < 1000; i++)
            {
                Console.WriteLine(TestClass.Instance.Id);
            }

            Console.Write("Press any key to continue:");
            Console.ReadKey();
        }

        private class TestClass
        {
            private static readonly LazyInit<TestClass> _instance = new LazyInit<TestClass>(() => new TestClass(), LazyInitMode.EnsureSingleExecution);

            public static TestClass Instance
            {
                get { return _instance.Value; }
            }

            private TestClass()
            {
                Debug.WriteLine("TestClass Constructor");
                Id = Guid.NewGuid();
            }

            public Guid Id { get; private set; }
        }
    }
}
¿Fue útil?

Solución

Versión corta: haga que la estática no sea de solo lectura y solucionará el error que está experimentando.

Versión larga: esta es una parte muy incomprendida de C #. Cuando accede a una estructura, está accediendo a una copia de la estructura. La llamada subyacente de LazyInit.Value es una operación mutante. Normalmente, se realiza una copia de seguridad, pero en el caso de un campo de solo lectura, no hay forma de realizar la copia de seguridad y, por lo tanto, aún queda un valor no inicializado.

Explicación extremadamente detallada: http://ericlippert.com/2008/ 14/05 / mutating-readonly-structs /

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