C# Namespaces and Backward Compatibility – Part 1

Namespaces are a great way to organize code. However, I recently found out that even putting your classes in a carefully organized namespace hierarchy will not shield you from name conflict problems as you move to newer versions of .NET framework or third party libraries.

I ran into two rather unfortunate scenarios in the last couple of days. This post describes the first scenario (hence, “part 1”).

It was your class, but now it’s their class.

Long time ago, I created class Lazy<T> that implemented lazy initialization for objects of type T. One would use it like this:

using System;
using Ikriv.Util;

class Foo
    Lazy<DateTime> _someDate

    public Foo() { _someDate = new Lazy(CalculateDate); }
    private DateTime CalculateDate() { // some long calculation here }

This code worked perfectly under .NET 3.5 and earlier. But then, on a lucky day, Microsoft decided to implement their own Lazy<T> in .NET Framework 4, and put it in the System namespace. So, when I compile the above code under .NET 4, I get an error, saying that there is an ambiguity between System.Lazy and Ikriv.Util.Lazy.

If Lazy were not a template, I could have resolved it by specifying

using Lazy = Ikriv.Util.Lazy;

Unfortunately, this does not work with templates. So, now I have to choose between these options:

  • Fully qualify Ikriv.Util.Lazy every time it is used. Code readability will suffer.
  • Rename Ikriv.Util.Lazy to something else. This will change previously published interface, which is not good. Also, I can’t think of a better name: the very reason I had the name conflict is because Microsoft chose the same name as I did, probably because this is the most natural name for this class.
  • Convert the code to use System.Lazy instead of Ikriv.Util.Lazy. This will take time and some testing. Fortunately, the two classes are virtually identical, but we may not be that lucky next time.

Frankly, I don’t like any of those solutions.

How could I have avoided the problem? I am not sure. After all, I cannot anticipate what classes Microsoft will decide to throw into the System namespace in the future. I could probably prefix all my classes with something like Ivk (Ikriv.Util.IvkLazy?), but then what’s the point of namespaces? Also, Ivk peppered everywhere will affect code readability.

The good news is that we don’t upgrade to new version of .NET framework every day, so events of this kind should be rare.

Leave a Reply

Your email address will not be published. Required fields are marked *