Namespace and Class with the Same Name

Namespace and class with the same name?

I don't recommend you to name a class like its namespace, see this article.

The Framework Design Guidelines say in section 3.4 “do not use the
same name for a namespace and a type in that namespace”. That is:

namespace MyContainers.List 
{
public class List { … }
}

Why is this badness? Oh, let me count the ways.

You can get yourself into situations where you think you are referring
to one thing but in fact are referring to something else. Suppose you
end up in this unfortunate situation: you are writing Blah.DLL and
importing Foo.DLL and Bar.DLL, which, unfortunately, both have a type
called Foo:

// Foo.DLL: 
namespace Foo { public class Foo { } }

// Bar.DLL:
namespace Bar { public class Foo { } }

// Blah.DLL:
namespace Blah
{
using Foo;
using Bar;
class C { Foo foo; }
}

The compiler gives an error. “Foo” is ambiguous between Foo.Foo and
Bar.Foo.
Bummer. I guess I’ll fix that by fully qualifying the name:

   class C { Foo.Foo foo; } 

This now gives the ambiguity error “Foo in
Foo.Foo is ambiguous between Foo.Foo and Bar.Foo
”. We still don’t know
what the first Foo refers to, and until we can figure that out, we
don’t even bother to try to figure out what the second one refers to.

Differentiating class and namespace when class and namespace have the same name

You should avoid a scenario where you name your classes and namespaces the same. If you can't or using third party code, you can always refer to the namespace with the global:: keyword:

namespace A
{
class B
{

}

class A
{
public void f()
{
global::A.B var = new global::A.B();
}
}
}

Problem with identical namespace and class name in C#

C# will always prefer a namespace to a class in case of an ambiguity. If you add another class to LedgerCommander.A, it will become quite obvious: you'll still need to use A.A.a for accessing class A, but A.Foo will work fine.

Also note that this only works because MyClass is in LedgerCommander; if you put it into another namespace, you'd have to use using LedgerCommander; to get the same behaviour.

C# design guidelines are pretty specific about this (https://learn.microsoft.com/en-us/dotnet/standard/design-guidelines/names-of-namespaces):

DO NOT use the same name for a namespace and a type in that namespace.

The type binding doesn't backtrack. If there is an ambiguity, you will need to fully qualify the type name. Sometimes this is as easy as using the namespace and the type name (as in your case), but sometimes you'll need the full path, possibly including an extern alias (ouch). Just don't do it.

namespace and class has the same name

It isn't necessary to have separate class and namespace names, but indeed, the compiler gets confused sometimes. For all parties it is best to keep namespace names and class names separate.

If you do want to use the same name, you could help the compiler not get confused. Use a using for your class:

using XXClass = COM.XX.ZZ.XX;

Then you can use it like this:

XXClass.someMethod();

This is far from recommended, so I suggest to rename either of them.


Another reason this might fail is that someMethod isn't static. In that case the compiler thinks you are referring to XX-the-namespace. Try to instantiate XX first:

XX xx = new XX();
xx.someMethod();

Namespace with same name as a class name

This really depends on what you are trying to achieve. If you really want baz to sit under the foo.bar namespace because it is dependent/closely linked you to bar can make it a child class of bar:

namespace foo
{
public class bar
{
public class baz : EventArgs { ... }
}
}

You can now create a new instance as:

var test = new foo.bar.baz();

Import class that has the same name as a namespace

Your class is a constructor function. They will essentially merge as the namespaced objects are appended to the constructor function definition and you will have something like nested classes.
If you want to import only the Foo class, then you tricked yourself.

I can't say if it's good practice or not, but I use it to emulate nested classes.

The namespace and class can be imported by using:

import * as Foo from 'foo';


Related Topics



Leave a reply



Submit