sobota, 9 marca 2013

Późne generowanie obiektu

Ostatnio bawiłem się leniwą (późną) inicjalizacją obiektu przez klasę Lazy. Troszkę zaskoczyła mnie jej działanie. Chciałbym powielić jeden obiekt, który ma losowe wartości.
    public class ElementClient
    {
        public string Name = Path
.GetRandomFileName()
.Replace(".", "");

        public Guid Guid = Guid.NewGuid();
        public override string ToString()
        {
            return string.Format("Guid:{0} Name:{1}", Guid, Name);
        }
    }
Mamy pomocniczą metodę wyświetlająca elementy w liście
      private static void Print<T>(IEnumerable<T> elements)
        {
            foreach (var elementClient in elements)
            {
                Console.WriteLine(elementClient);
            }
        }
Jeżeli powielę jeden obiekt to dostaje takie same wartości.
            int repeatNumber = 5;
            var elements = Enumerable.Repeat(new ElementClient(), repeatNumber);
            Print(elements);
Ale chciałbym stworzyć 5 obiekty, które mają różne wartości. Więc muszę wcześniej stworzyć klasę, która inicjalizuje obiekt wtedy gdy dany obiekt będzie potrzebny.
    public class Invoker<T>
    {
        public T Value
        {
            get { return _func(); }
        }
        private Func<T> _func;
        public Invoker(Func<T> func)
        {
            _func = func;
        }
    }
            var elements2 = Enumerable
                .Repeat(new Invoker(() => 
                                        new ElementClient()), repeatNumber)
                .Select(x => x.Value)
                .ToList();
            Print(elements2);

To samo chcemy zrobić za pomocą klasy Lazy<T>
     var elements3 = Enumerable
                .Repeat(new Lazy<ElementClient>(), repeatNumber)
                .Select(x => x.Value)
                .ToList();
            Print(elements3);
Ale dostałem takie same wartości. Uważaj na klasę Lazy<T> - nie zawsze działa tak jak myślisz.

Brak komentarzy:

Prześlij komentarz