Lazy class (advanced)

OK, this is no joke. This class really exists.

Not many programmers come across this class. At first glance it seems to be useless. Let’s have a closer look!
Imagine the following situation. You are initializing objects. Each of them takes a lot of time and uses many resources. There is no load balancing. Some of them may be used simultaneously, so it is not one or the other. The problem is that you don’t know, which object will be needed. It could be that you don’t need any object at all. Nevertheless you want to provide each object to the system as if they were initialized already. That way you don’t have to deal with any initialization later during the running program.

I included a short example about Bill Gates. Let’s say he has too many cars, so he feels the agony of choice. Early in the morning Bill is standing in his garage. He needs a car to go to the beach, but there are simply too many cars to choose from. One of his many gardeners recommends the Porsche. Well, the final choice is at the whim of Bill Gates. Hypothetically he might also need a second car today. His new 19-year-old girl friend had an overnight stay … on the couch. Yeah, that’s life 😉

I am sure you are often using LINQ. It uses a similar concept. Linq does not execute until the point you access the query result. When the example program calls “… select x.GetSomething()”, then you do not see any output from the method GetSomething(), which would be “What about an ice cream?”. “Where is my lunch?” prints first. And when we call lYummy.First() to get the first object from the query (well, there is only one), only then you see GetSomething() executing.

Too Lazy or just right?

using System;
using System.Collections.Generic;
using System.Linq;

namespace DemoApp {
   public class VeryLazy {
      public class NotNow {
         public NotNow() { Console.WriteLine("executing constructor"); }
         public void DoSomething() { Console.WriteLine("Zzzzzz... Jeez, you woke me up!"); }
         public string GetSomething() {
            Console.WriteLine("What about an ice cream?");
            return "ice cream";
         }
      } // class      

      public class BillGatesGarage {
         Lazy<NotNow> Porsche = new Lazy<NotNow>();
         Lazy<NotNow> Ferrari = new Lazy<NotNow>();
         Lazy<NotNow> Maserati = new Lazy<NotNow>();
         Lazy<NotNow> Lamborghini = new Lazy<NotNow>();

         public enum eCoolness { eSmart, eShowOff, eFast, eFun }
         public NotNow getCar(eCoolness xCoolness) {
            Console.WriteLine();
            Console.WriteLine("Sleeping cars:");
            Console.WriteLine("Porsche " + !Porsche.IsValueCreated);
            Console.WriteLine("Ferrari " + !Ferrari.IsValueCreated);
            Console.WriteLine("Maserati " + !Maserati.IsValueCreated);
            Console.WriteLine("Lamborghini " + !Lamborghini.IsValueCreated);
            switch (xCoolness) {
               case eCoolness.eSmart: return Porsche.Value;
               case eCoolness.eShowOff: return Ferrari.Value;
               case eCoolness.eFast: return Maserati.Value;
               case eCoolness.eFun: return Lamborghini.Value;
            }
            return null;
         }
      } // class

      public static void test() {
         List<NotNow> lList = new List<NotNow>();
         lList.Add(new NotNow());         
         var lYummy = from x in lList select x.GetSomething();
         Console.WriteLine("Where is my lunch?");
         Console.WriteLine("I got an " + lYummy.First() + " for you!");

         Console.WriteLine();
         Lazy<NotNow> lLazy = new Lazy<NotNow>();
         Console.WriteLine("Object created already? " + lLazy.IsValueCreated);
         Console.WriteLine("No worries! Let's create an instance now:");
         NotNow lNotNow = lLazy.Value;
         Console.WriteLine("Object created already? " + lLazy.IsValueCreated);
         if (lLazy.IsValueCreated) lNotNow.DoSomething();

         Console.WriteLine();
         Console.WriteLine("All engines warmed up?");
         BillGatesGarage lGarage = new BillGatesGarage();
         NotNow lBrumBrum = lGarage.getCar(BillGatesGarage.eCoolness.eSmart);
         lBrumBrum.DoSomething();
         Console.WriteLine("Oh dear, he just changed his mind");
         NotNow lWhooosh = lGarage.getCar(BillGatesGarage.eCoolness.eFast);
         lWhooosh.DoSomething();

         // check cars
         lGarage.getCar(BillGatesGarage.eCoolness.eFast);
      } //

   } // class
} // namespace

example output:
executing constructor
Where is my lunch?
What about an ice cream?
I got an ice cream for you!

Object created already? False
No worries! Let’s create an instance now:
executing constructor
Object created already? True
Zzzzzz… Jeez, you woke me up!

All engines warmed up?

Sleeping cars:
Porsche True
Ferrari True
Maserati True
Lamborghini True
executing constructor
Zzzzzz… Jeez, you woke me up!
Oh dear, he just changed his mind

Sleeping cars:
Porsche False
Ferrari True
Maserati True
Lamborghini True
executing constructor
Zzzzzz… Jeez, you woke me up!

Sleeping cars:
Porsche False
Ferrari True
Maserati False
Lamborghini True

About Bastian M.K. Ohta

Happiness only real when shared.

Posted on March 11, 2014, in Advanced, C# and tagged , , , , , , , . Bookmark the permalink. Leave a comment.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: