#947 – Specifying Lazy Instantiation Using a Lambda Expression

When you are declaring an object that will be lazily instantiated, you pass a delegate instance to the Lazy<T> constructor, where the delegate instance indicates a method to be called that will instantiate the underlying object.

For example, you could do the following:

        private static Lazy<Dog> dog1 = new Lazy<Dog>(CreateDefaultDog);
        private static Dog CreateDefaultDog()
        {
            return new Dog("Lassie");
        }

Very often, however, you’ll want to pass some parameter value to the delegate or just invoke one of the normal constructors for the object, passing one or more parameters to the constructor.  You can do this by just using a lambda expression, as follows:

        private static Lazy<Dog> dog2 = new Lazy<Dog>(() => new Dog("Lassie"));
Advertisement

#946 – Specifying Whether Lazy Instantiated Object Should Be Thread-Safe

You can use the Lazy<T> class to declare an object that will be lazily instantiated–that is, created just before it is used.

In the example below, we indicate that the listOfAllFamousDogs object should only be created (by calling GenerateBigListOfFamousDogs) just before it is referenced.  The GenerateBigListOfFamousDogs method returns an instance of List<Dog>.

private static Lazy<List<Dog>> listOfAllFamousDogs = new Lazy<List<Dog>> (GenerateBigListOfFamousDogs);

In the Lazy<T> constructor, we specify a delegate that will be called to initialize our object.  By default, this results in a thread-safe implementation that lazily instantiates the specified object.

If we do not need thread-safety, we can pass a second parameter to the Lazy<T> constructor, with a value of false.

        // No need for thread safety
        private static Lazy<List<Dog>> listOfAllFamousDogs = new Lazy<List<Dog>> (GenerateBigListOfFamousDogs, false);

#945 – Lazy Instantiation, an Easier Solution

The previous post showed how to implement lazy instantiation in a thread-safe manner, waiting to initialize an object until it is first used.

.NET 4.0 introduced the Lazy<T> class, which makes lazy instantiation much easier.  If you have an object that you want to instantiate as late as possible, you declare it to be of type Lazy<T>, where is the core type of your object.  You also specify a method to be called to do the actual initialization of the object.

So instead of doing this:

        private static List<Dog> listOfAllFamousDogs = GenerateBigListOfFamousDogs();
        public bool IsFamous
        {
            get { return listOfAllFamousDogs.Contains(this); }
        }

You do this:

        private static Lazy<List<Dog>> listOfAllFamousDogs = new Lazy<List<Dog>> (GenerateBigListOfFamousDogs);
        public bool IsFamous
        {
            get { return listOfAllFamousDogs.Value.Contains(this); }
        }

Note that you also use the Value property of the new Lazy<T> object to get at the underlying object.

#944 – Lazy Instantiation, Solution #2

The previous post showed one way to achieve lazy instantiation–waiting to initialize a data object until just before it’s needed.  The problem with this example, however, was that it wasn’t thread-safe.  Two threads could simultaneously check to see if the object is initialized and both determine that it is not.  Both threads would then try to initialize the object.

The code below updates the earlier example, making it thread-safe.

        private static List listOfAllFamousDogs = null;
        private static readonly object initLock = new object();

        private static List GenerateBigListOfFamousDogs()
        {
            Console.WriteLine("Loading big list of famous dogs!");
            List bigList = new List();
            bigList.Add(new Dog("Lassie"));
            bigList.Add(new Dog("Rin Tin Tin"));
            // load 1,000 more dogs here

            return bigList;
        }

        public bool IsFamous
        {
            get
            {
                lock (initLock)
                {
                    if (listOfAllFamousDogs == null)
                        listOfAllFamousDogs = GenerateBigListOfFamousDogs();
                }

                return listOfAllFamousDogs.Contains(this);
            }
        }

Next time, we’ll see an easier way to do this in .NET 4.0 or later.

#943 – Lazy Instantiation, Solution #1

There are cases when we have a large amount of data to allocate in a class, either in an instance of the class or as static data.  We want to allocate and initialize the data as late as possible, i.e. just before we need to use the data.  This is know as lazy instantiation.

One method for lazy instantiation is to check to see if the data is instantiated, wherever we try to use it.

        private static List<Dog> listOfAllFamousDogs = null;

        private static List<Dog> GenerateBigListOfFamousDogs()
        {
            Console.WriteLine("Loading big list of famous dogs!");
            List<Dog> bigList = new List<Dog>();
            bigList.Add(new Dog("Lassie"));
            bigList.Add(new Dog("Rin Tin Tin"));
            // load 1,000 more dogs here

            return bigList;
        }

        public bool IsFamous
        {
            get
            {
                if (listOfAllFamousDogs == null)
                    listOfAllFamousDogs = GenerateBigListOfFamousDogs();

                return listOfAllFamousDogs.Contains(this);
            }
        }

We get lazy instantiation here–the list isn’t initialized until we use the IsFamous property.  This solution, however, is not thread-safe.

#942 – The Case for Lazy Instantiation

Assume that we create some large data item in an object, e.g. the listofAllFamousDogs object in the sample below:

    public class Dog
    {
        public string Name { get; set; }

        public Dog(string name)
        {
            Name = name;
        }

        public void Bark()
        {
            Console.WriteLine("Woof!");
        }

        private static List<Dog> listOfAllFamousDogs = GenerateBigListOfFamousDogs();

        private static List<Dog> GenerateBigListOfFamousDogs()
        {
            Console.WriteLine("Loading big list of famous dogs!");
            List<Dog> bigList = new List<Dog>();
            bigList.Add(new Dog("Lassie"));
            bigList.Add(new Dog("Rin Tin Tin"));
            // load 1,000 more dogs here

            return bigList;
        }

        public bool IsFamous
        {
            get { return listOfAllFamousDogs.Contains(this); }
        }
    }

The problem with this is that we end up creating the big list when we first use the class–whether or not we’ll later use the IsFamous property.

            Dog bob = new Dog("Bob");
            bob.Bark();

942-001
What we need is to lazily instantiate this list.  That is–wait to create the list until we actually need it.

Ad Free

I’ve turned off ads on 2,000 Things You Should Know about C#.  For a full explanation, click here.

#757 – Books on Object-Oriented Programming

Since C# is an object-oriented language, it can be helpful to study object-oriented design and programming techniques.  Here are some good books that focus on object-oriented design or programming.

  • Applying UML and Patterns: An Introduction to Object-Oriented Analysis and Design and Iterative Development (3rd edition). Craig Larman. 2004.
  • Beginning C# Object-Oriented Programming. Dan Clark. 2011.
  • Design Patterns: Elements of Reusable Object-Oriented Software. Gamma, Helm, Johnson, Vlissides. 1994.
  • Designing Object-Oriented Software. Wirfs-Brock, Wilkerson, Wiener. 1990
  • Growing Object-Oriented Software, Guided by Tests. Freeman, Pryce. 2009.
  • Head First Object-Oriented Analysis and Design. McLaughlin, Pollice, West. 2006.
  • An Introduction to Object-Oriented Programming (3rd edition). Timothy Budd. 2001.
  • Object-Oriented Analysis and Design with Applications (3rd edition). Booch, Maksimchuk, et al. 2007.
  • Object-Oriented Design and Patterns. Cay S. Horstmann. 2005.
  • Object-Oriented Software Construction (2nd edition). Bertrand Meyer. 2000.
  • The Object-Oriented Thought Process (3rd edition). Matt Weisfeld. 2008.
  • OOP Demystified. Keogh, Giannini. 2004.
  • Principles of Object-Oriented Analysis and Design. Martin, Odell. 1993.

#750 – Use xUnit.net for Unit Testing

On Codeplex, you’ll find a project called xUnit.net–a unit testing framework that allows you to write and run unit tests against your code.

To use xUnit.net, you write test methods that invoke the methods that you want to test and then make various assertions about the expected results.

For example, assume that you have a Divide method:

        public static double Divide(double a, double b)

You can then use xUnit.net to write a test method that makes several assertions about what it expects the results of calling the Divide method to be.

    public class SomeTests
    {
        [Fact]
        public void DivideTest()
        {
            Assert.Equal(3.0, MathClass.Divide(6.0, 2.0));
            Assert.InRange<double>(MathClass.Divide(1.0, 3.0), 0.3333, 0.3334);

            Assert.Equal(3.14, MathClass.Divide(Math.PI, 1.0));  // Fails!
        }
    }

After you build your project, you can use the xUnit test console to run your unit tests.  It will indicate how many tests passed or failed.

750-001

#749 – Example of Some C# Design Patterns

There is a nice little project over at Codeplex that includes a bunch of examples of common design patterns, written in C#.

Tutorial: Common Design Patterns in C# 4.0

This project appears to be only partially done, but does include an implementation of the following design patterns:

  • Abstract Factory
  • Builder
  • Factory Method
  • Prototype
  • Singleton
  • Adapter
  • Bridge

The project has placeholders for other patterns, including:

  • Composite
  • Decorator
  • Facade
  • Flyweight
  • Proxy
  • Chain of Responsibility
  • Command
  • Interpreter
  • Iterator
  • Mediator
  • Memento
  • Observer
  • State
  • Strategy
  • Template Method
  • Visitor

These patterns all come from the well known “Gang of Four” book, Design Patterns: Elements of Reusable Object-Oriented Software.  (Gamma, Helm, Johnson, and Vlissides).

The project has been dormant since July, 2011.  So this is perhaps an opportunity for some other software developers out there to contribute to the project by implementing some of the remaining patterns.