Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
584 views
in Technique[技术] by (71.8m points)

c# - Namespace collisions

How is it possible that .NET is finding the wrong 'MyType' in this scenario?

I have a type A.B.C.D.MyType in a project that I'm working on, and I'm referencing a DLL that has a type A.B.MyType? I do not have any 'using A.B;' statements anywhere in my code, and I do have 'using A.B.C.D;'. When I compile, the compiler thinks any naked reference to 'MyType' means 'A.B.MyType'.

I know I could just rename the class or use an alias, but I'm wondering how this is even possible.

Any ideas?

Thanks!

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Are you working in a namespace that is under A.B namespace? (for example A.B.X) if so the C# namespace resolutions (ECMA-334 C# Language Specification : 10.8 10.8 Namespace and type names) says:

... for each namespace N, starting with the namespace in which the namespace-or-typename occurs, continuing with each enclosing namespace (if any), and ending with the global namespace, the following steps are evaluated until an entity is located...

and then followed by:

If K is zero and the namespace declaration contains an extern-alias-directive or using-aliasdirective that associates the name I with an imported namespace or type, then the namespace-or-type-name refers to that namespace or type

This means that name resolution starts at the current namespace and searches all namespaces up to the root, and only after this hierarchical search ends, then the namespaces imported with the using clause are searched.

The following example prints "Ns1.Foo"

using Ns1.Foo.Foo2;

namespace Ns1.Foo
{
    class Foo
    {
        public void Print()
        {
            System.Console.WriteLine("Ns1.Foo");
        }
    }
}

namespace Ns1.Foo.Foo2
{
    class Foo
    {
        public void Print()
        {
            System.Console.WriteLine("Ns1.Foo.Foo2");
        }
    }
}

namespace Ns1.Foo.Bar
{
    class Bar
    {
        public void Print()
        {
            new Foo().Print();
        }

        static void Main()
        {
            new Bar().Print();
        }
    }
}

Edit: Adding a using clause inside a namespace, will make so that the namespace is searched before the hierarchical search of current namespace is done is done. Change the example to:

namespace Ns1.Foo.Bar
{
    using Ns1.Foo.Foo2;
    class Bar
    {
        public void Print()
        {
            new Foo().Print();
        }

        static void Main()
        {
            new Bar().Print();
        }
    }
}

and Ns1.Foo.Foo2 will be printed.

Edit: changed example


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...