Directory Freebies VS CheatSheet Forum

RSS

Email

Translate

Home About Archive Privacy Contact Advertise Write for Dev102
Posted by Shahar Y on Oct 16th, 2008 | Filed under .Net, C# |

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: , , , , , ,

8 Responses to “Naming Collisions And The Using Directive”


  1. morrijr Said on Oct 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 Oct 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 Oct 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 Oct 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 Oct 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 Oct 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 Oct 17, 2008 :

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

  8. Sean Said on Oct 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.

Post a Comment

Write Article for Dev102

Write for Dev102!

We pay for user submitted tutorials and articles that we publish. Anyone can send in a contribution

Learn More