Blog

  • Home /
  • Blog /
  • Be Careful With the var Keyword and Expression Builders

Be Careful With the var Keyword and Expression Builders

March 21, 2009

I just want to point out a small tidbit I ran into earlier this week. I was using the following simplified expression builder that provides a fluent interface for creating an instance of a Product.

public class Product
{
    public Double Price { get; private set; }
    public String Name { get; private set; }
    public String Manufacturer { get; private set; }

    public Product(String name, String manufacturer,
                   Double price)
    {
        Price = price;
        Name = name;
        Manufacturer = manufacturer;
    }
}

public class ProductBuilder
{
    private String Manufacturer { get; set; }
    private String Name { get; set; }
    private Double Price { get; set; }

    public static ProductBuilder CreateProduct()
    {
        return new ProductBuilder();
    }

    public ProductBuilder Named(String name)
    {
        Name = name;
        return this;
    }

    public ProductBuilder ManufacturedBy(
        String manufacturer)
    {
        Manufacturer = manufacturer;
        return this;
    }

    public ProductBuilder Priced(Double price)
    {
       Price = price;
        return this;
    }

    public static implicit operator Product(
        ProductBuilder builder)
    {
        return builder.Build();
    }

    private Product Build()
    {
        return new Product(Name, Manufacturer, Price);
    }
}

The following code is an example of how to use this expression builder.

var product = ProductBuilder
    .CreateProduct()
    .Named("iPod Touch")
    .ManufacturedBy("Apple")
    .Priced(273);

There is one minor inconvenience with this code. One may think that the product variable contains an instance of a Product. Unfortunately, this is not the case. The product variable however contains an instance of ProductBuilder and not an instance of Product because the implicit cast operator is never called. How would the compiler know that you want to keep a reference to Product and not a ProductBuilder? Bringing in a bit more ceremony makes this code more easier to comprehend without side effects.

Product product = ProductBuilder
    .CreateProduct()
    .Named("iPod Touch")
    .ManufacturedBy("Apple")
    .Priced(273);

A small price to pay for better readability. On the other hand, you will never encounter this when you pass in the Product to another method.

var product = ProductBuilder
    .CreateProduct()
    .Named("iPod Touch")
    .ManufacturedBy("Apple")
    .Priced(273);

DoSomethingWith(product);

public void DoSomethingWith(Product product)
{
    // ...
}

In this case the implicit cast operator does get called when passing the ProductBuilder instance to the DoSomethingWith method. If lazy initialization is what you want, then the var keyword is the perfect match for this.

var product = ProductBuilder
    .CreateProduct()
    .Named("iPod Touch");

// Do something else
product.ManufacturedBy("Apple")
    .Priced(273);

This may all be straightforward stuff, but I noticed that it kept bugging me every time I didn't paid attention.

If you and your team want to learn more about how to write maintainable unit tests and get the most out of TDD practices, make sure to have look at our trainings and workshops or check out the books section. Feel free to reach out at infonull@nullprincipal-itnull.be.

Profile picture of Jan Van Ryswyck

Jan Van Ryswyck

Thank you for visiting my blog. I’m a professional software developer since Y2K. A blogger since Y2K+5. Provider of training and coaching in XP practices. Curator of the Awesome Talks list. Past organizer of the European Virtual ALT.NET meetings. Thinking and learning about all kinds of technologies since forever.

Comments

About

Thank you for visiting my website. I’m a professional software developer since Y2K. A blogger since Y2K+5. Author of Writing Maintainable Unit Tests. Provider of training and coaching in XP practices. Curator of the Awesome Talks list. Thinking and learning about all kinds of technologies since forever.

Contact information

(+32) 496 38 00 82

infonull@nullprincipal-itnull.be