C# Coding Style – Switch vs Dictionary for Object Assignment

ccoding-style

Recently, I've come to prefer mapping 1-1 relationships using Dictionaries instead of Switch statements. I find it to be a little faster to write and easier to mentally process. Unfortunately, when mapping to a new instance of an object, I don't want to define it like this:

var fooDict = new Dictionary<int, IBigObject>()
{
    { 0, new Foo() }, // Creates an instance of Foo
    { 1, new Bar() }, // Creates an instance of Bar
    { 2, new Baz() }  // Creates an instance of Baz
}

var quux = fooDict[0]; // quux references Foo

Given that construct, I've wasted CPU cycles and memory creating 3 objects, doing whatever their constructors might contain, and only ended up using one of them. I also believe that mapping other objects to fooDict[0] in this case will cause them to reference the same thing, rather than creating a new instance of Foo as intended. A solution would be to use a lambda instead:

var fooDict = new Dictionary<int, Func<IBigObject>>()
{
    { 0, () => new Foo() }, // Returns a new instance of Foo when invoked
    { 1, () => new Bar() }, // Ditto Bar
    { 2, () => new Baz() }  // Ditto Baz
}

var quux = fooDict[0](); // equivalent to saying 'var quux = new Foo();'

Is this getting to a point where it's too confusing? It's easy to miss that () on the end. Or is mapping to a function/expression a fairly common practice? The alternative would be to use a switch:

IBigObject quux;
switch(someInt)
{
    case 0: quux = new Foo(); break;
    case 1: quux = new Bar(); break;
    case 2: quux = new Baz(); break;
}

Which invocation is more acceptable?

  • Dictionary, for faster lookups and fewer keywords (case and break)
  • Switch: More commonly found in code, doesn't require the use of a
    Func<> object for indirection.

Best Answer

That's an interesting take on the factory pattern. I like the combination of the Dictionary and the lambda expression; it made me look at that container in a new way.

I'm ignoring the concern in your question about CPU cycles as you mentioned in the comments that the non-lambda approach doesn't provide what you need.

I think either approach (switch vs. Dictionary + lambda) is going to be fine. The only limitation is that by using the Dictionary, you are limiting the types of inputs you could receive in order to generate the returned class.

Using a switch statement would provide you more flexibility on input parameters. However, if this got to be an issue, you could wrap the Dictionary inside of a method and have the same end result.

If it's new for your team, comment the code and explain what's going on. Call for a team code review, walk them through what was done and make them aware of it. Other than that, it looks fine.