Ganz schön „lazy“, was!?

Da gibts doch immer wieder coole Features in C#, die wirklich nützlich sind, welche aber kaum jemand einsetzt. Schon was von Lazy<T> gehört?

Die Lazy<T> -Klasse wurde mit der Frameworkversion 4 eingeführt und dient in erster Linie dazu, Objekte verzögert zu initialisieren. Aus meiner Sicht ist dies ´ne wirklich coole Sache, da man sich damit die Getter von Properties frei von unübersichtlicher Logik halten kann. Die Idee hinter Lazy<T> ist dabei denkbar einfach: Man übergibt dem Konstruktor der Lazy-Klasse einfach einen Delegaten, der beim ersten Zugriff auf die Value-Eigenschaft der Klasse ausgeführt wird. Gedacht ist dies vor allem für Objekte, die entweder sehr ressourcenintensiv sind und/ oder nur in bestimmten Konstellationen des Programmablaufes benötigt werden und deshalb nicht unnötigerweise schon bei der Instanzierung des beherbergenden Objektes geladen werden muss.

Angenommen wir haben eine Klasse Customer und möchten nicht implizit bei jeder Instanzierung des Objektes alle Aufträge mit laden, weil wir die Auflistung beispielsweise recht groß sein kann und nur in bestimmten Situationen benötigt wird,dann hätten wir das bisher wahrscheinlich wie folgt gelöst:

    public class Customer
    {
        private readonly IRepository repository = null;
        private IEnumerable<IOrder> orders = null;

        public Customer(IDataRecord dataRecord, IRepository repository)
        {
            this.repository = repository;
            this.Id = dataRecord.GetGuid(0);
            this.CompanyName = dataRecord.GetString(1);
        }

        public Guid Id { get; private set; }

        public string CompanyName { get; private set; }

        public IEnumerable<IOrder> Orders
        {
            get
            {
                if (this.orders == null)
                {
                    this.orders = 
                        this.repository.GetOrdersByCustomerId(this.Id);
                }

                return this.orders;
            }
        }
    }

Beim Aufruf der Eigenschaft wird geprüft, ob das private Feld schon initialisiert wurde. Wenn nicht, wird das Repository befragt und die Daten werden geladen. Nicht schön daran ist allerdings, dass der Getter ziemlich viel Logik enthält. Ggf. kommt dies ja ähnlich in mehreren Properties vor, so dass der Code dann schnell unleserlich wird.

Eleganter geht das Ganze mit der Lazy>T>-Klasse. Das sieht dann wie folgt aus:

    public class Customer
    {
        private readonly IRepository repository = null;
        private readonly Lazy<IEnumerable<IOrder>> orders = null;

        public Customer(IDataRecord dataRecord, IRepository repository)
        {
            this.repository = repository;
            this.Id = dataRecord.GetGuid(0);
            this.CompanyName = dataRecord.GetString(1);

            this.orders = new Lazy<IEnumerable<IOrder>>(
                () => this.repository.GetOrdersByCustomerId(this.Id));
        }

        public Guid Id { get; private set; }

        public string CompanyName { get; private set; }

        public IEnumerable<IOrder> Orders
        {
            get
            {
                return this.orders.Value;
            }
        }
    }

Die Initialisierungslogik wird uns nun von der Lazy<T>-Klasse abgenommen, so dass wir uns nicht mehr darum kümmern müssen. Sie sorgt zuverlässig dafür, dass der Aufruf gegen das Repository während der Lebenszeit der Customer-Objektes nur einmalig erfolgt. Die Anzahl der Code-Zeilen wurde reduziert und damit die Lesbarkeit erhöht. Richtig bemerkbar macht sich dies natürlich erst, wenn die Klassen größer sind. Guter Stil ist es aus meiner Sicht allemal, die Lazy<T>- Klasse zu verwenden.

Weitere Infos zur Lazy<T>- Klasse gibt es in der MSDN: http://msdn.microsoft.com/de-de/library/dd642331.aspx

Über Feedback, Kritik oder Anregungen zum Blog-Beitrag würde ich mich freuen.

Artikel in der letzten Ausgabe der Visual Studio One

In der letzten Ausgabe des Fachmagazins Visual Studio One rund um Visual Studio und .NET habe ich einen Artikel zum Thema „Refactoring“ veröffentlicht. Die Visual Studio One stellt den Artikel auf der Webseite als PDF bereit.

http://www.visualstudio1.de/Zufallsartikel1.pdf

oder einfach mal http://www.visualstudio1.de besuchen.

Viel Spaß!