namingCollision

Are you familiar with the following C# compilation error: “CS0104: ClassA is an ambiguous reference between Namespace1.ClassA and Namespace2.ClassA“? It happens when your program contains using directives for two namespaces and your code references a name that appears in both namespaces.

Lets work with a concrete example:

using System.Windows;
using Dev102.Freebies.SampleCode.Geometry.ThreeDimensions;

namespace NamingCollision
{
    public class Class1
    {
        static void Main()
        {
            Vector vec = new Vector();
            Console.WriteLine("Vector X = {0}", vec.X);
        }
    }
}

This code contains using directives for both: System.Windows and Dev102.Freebies.SampleCode.Geometry.ThreeDimensions (it uses classes which are defined in those namespaces). The Vector class is defined in both namespaces, so the compiler can’t resolve that ambiguity. Most software developer would solve that error by referencing the Vector class with its full name:

namespace NamingCollision
{
    public class Class1
    {
        static void Main()
        {
            Dev102.Freebies.SampleCode.Geometry.ThreeDimensions.Vector vec =
                new Dev102.Freebies.SampleCode.Geometry.ThreeDimensions.Vector();
            Console.WriteLine("Vector X = {0}", vec.X);
        }
    }
}

Well, I don’t really like this code because it contains a lot of irrelevant text which distracts you from what that code really does. There is a way to make this code more readable by simply creating an alias for the namespace:

using Dev102Geometry = Dev102.Freebies.SampleCode.Geometry.ThreeDimensions;

namespace NamingCollision
{
    public class Class1
    {
        static void Main()
        {
            Dev102Geometry.Vector vec = new Dev102Geometry.Vector();
            Console.WriteLine("Vector X = {0}", vec.X);
        }
    }
}

Isn’t it much better? I created a using alias to make it easier to qualify an identifier to the long Dev102 namespace . The alias is called Dev102Geometry and is used instead of the actual namespace so the code is much more readable now. I assume that you are already familiar with the concept of the using alias but did you ever really used it? I know, by reading a lot of code, that most of us won’t apply this method when there is a naming collision. I wrote this article to remind you that you can solve the ambiguous reference error with a better solution than just referencing the class with its full name.

Tags :

9 Responses to “Naming Collisions And The Using Directive”


  1. morrijr

    Said on October 17, 2008 :

    You don’t need the entire namespace, just enough for the compiler to identify the class you mean…

    using System.Windows;
    using Dev102.Freebies.SampleCode.Geometry.ThreeDimentions;

    namespace NamingCollision
    {
    public class Class1
    {
    static void Main()
    {
    ThreeDimentions.Vector vec = new ThreeDimentions.Vector();
    Console.WriteLine(“Vector X = {0}”, vec.X);
    }
    }
    }

    By doing the using alias you’ve given anyone who is not familiar with the code something else they need to lookup/discover before they gain an understanding of the code.

  2. Shahar Y

    Said on October 17, 2008 :

    @ morrijr

    Did you try to compile your code?
    It doesn’t compile, otherwise I wouldn’t write this post :)

    The compilation error is: “The type or namespace name ‘ThreeDimentions’ could not be found (are you missing a using directive or an assembly reference?)”

  3. Chris Marisic

    Said on October 17, 2008 :

    And this post is one of the reasons I use Jetbrains Resharper with code development as it will automatically clean up using statements and namespaced access to classes to the shortest phrases possible and will even create using aliases if the situation warrants it automatically.

  4. morrijr

    Said on October 17, 2008 :

    Ok, try changing

    using Dev102.Freebies.SampleCode.Geometry.ThreeDimentions;

    to

    using Dev102.Freebies.SampleCode.Geometry;

    btw, I assume you mean dimensions not dimentions.

  5. Shahar Y

    Said on October 17, 2008 :

    @ morrijr

    1) It won’t compile, believe me I already tried every other solution.

    2) Yes you are right it is Dimensions… Will fix it

  6. morrijr

    Said on October 17, 2008 :

    Your right, I was thinking of when you are deriving classes…

    namespace Dev102.Freebies.SampleCode.Geometry.ThreeDimensions
    {
    public class Vector
    {
    }
    }

    namespace Dev102.Freebies.SampleCode.Geometry.FourDimensions
    {
    public class Vector : ThreeDimensions.Vector
    {
    }
    }

    Interesting that it works there but not when declaring or instantiating… Oh hum. Live and learn. Still not keen on using alias in that case though :)

  7. logicalmind

    Said on October 17, 2008 :

    Just imagine if namespaces were lower case like in java. this would be a non-issue….

  8. Sean

    Said on October 18, 2008 :

    logicalmind, what does casing have to do with a naming collision? If two types exist in two or more namespaces for which are both in scope, the casing is completely irrelevant.

    Back on topic, I’m not a fan of this solution because of readability. Sure, there are a lot of extra characters by using the fully qualified name, but the extra characters are limited to the declaration and instantiation of the objects, so we’re likely talking about only a few lines of code.

  9. Delerium

    Said on May 3, 2011 :

    Thanks alot for this… Exactly what I was looking for.

    As for what Sean said, it’s not only a few lines of code in all cases. Take enum naming collisions for instance. Any time you want to reference that enum, you have to type out the full namespace. In my example, the collision occurs on the enum “Keys” between System.Windows.Forms and Microsoft.Xna.Framework.Input. When doing keyboard mapping, typing out or even copy pasting Microsoft.Xna.Framework.Input.Keys over and over will make you go mad. Not to mention it clutters up your code to the point of not being able to make out what is going on.

Post a Comment