Question

Mise à jour pour les futurs lecteurs: à la sortie de .NET 4, LazyInit < T / gt; du CTP aura été renommé en Lazy < T > et sera modifié d'une structure à une classe, donc très peu de cela s'appliquera, sauf pour illustrer pourquoi les structures mutables peuvent être problématiques si vous ne faites pas attention.

J'ai expérimenté LazyInit dans le CTP de juin de Parallel Extensions et je m'attendrais à ce que le code suivant imprime le même Guid mille fois, mais à la place, il imprime un millier de Guids différents. De toute évidence, il me manque quelque chose d’évident sur la façon dont LazyInit est censé fonctionner, et je vous serais reconnaissant de bien vouloir faire remarquer ce qu’il en est.

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; }
        }
    }
}
Était-ce utile?

La solution

Version courte: créez une statique non en lecture seule et elle corrigera le bogue que vous rencontrez.

Version longue: Ceci est une partie très mal comprise de C #. Lorsque vous accédez à une structure, vous accédez à une copie de cette structure. L'appel sous-jacent de LazyInit.Value est une opération de mutation. Normalement, une copie est effectuée, mais dans le cas d'un champ en lecture seule, il n'y a aucun moyen d'effectuer la copie, ce qui vous laisse toujours une valeur non initialisée.

Explication extrêmement détaillée: http://ericlippert.com/2008/ 05/14 / mutating-readonly-structs /

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