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<datetime>(CalculateDate); }
private DateTime CalculateDate() {
}</datetime>
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 a new version of .NET framework every day, so events of this kind should be rare.
CodeProject