C# : Why is First namespace redundant?

903 views Asked by At

This is a little spooky.

I'm thinking there must be a setting somewhere that explains why this is happening.

In our solution there are about 50 different projects. For the most part, the libraries start with the namespace OurCompany.

We have OurComany.This.That and OurCompany.Foo.Bar... etc.

There is a namespace/class clash between an external library with the namespace

OurCompany.Foo.Bar

And a class that is qualified like so..

OurCompany.Some.Location.Foo

The error goes like this:

Error   75  The type or namespace name 'MethodName' does not exist in the
namespace 'OurCompany.Foo' (are you missing an assembly reference?)

Even Resharper gives me a "Qualifier is redundant" message when I fully qualify anything under the "OurCompany" namespace.. i.e.

OurCompany.Some.Location.Foo.MethodName();
//OurCompany is redundant

I cannot figure out what on earth is doing this. The solution is pretty huge, so ripping things apart to try and reverse engineer the problem is not a great solution for me.

I should state that if I use...

Some.Location.Foo.MethodName(); //Leaving out OurCompany

...the Resharper message goes away.

2

There are 2 answers

3
Ben Nesson On BEST ANSWER

I thought I understood what was happening here, but now I'm seeing some weird behavior that's making me question my understanding of C#'s namespace scoping behavior.

Obviously, the basic issue is scoping. Presumably, you're working on something in some namespace under OurCompany; let's just say for sake of argument, you're in OurCompany.This.That. Automatically, any types or namespaces found directly in the OurCompany.This.That, OurCompany.This, and OurCompany namespaces are in scope, no usings required. This is why things broke as soon as an assembly with an OurCompany.Foo namespace got involved (everything in OurCompany is in scope by default, including the Foo namespace, and namespaces [apparently] take priority) and also why you're getting the redundant namespace warnings (the Some namespace is defined in the OurCompany namespace, so it's automatically in scope).

But trying to repro this behavior, I encountered something strange. I created one file to hold the rest of the relevant world:

namespace OurCompany
{
    namespace Some
    {
        namespace Location
        {
            public class Foo
            {
                public static void MethodName() { }
            }
        }
    }

    namespace Foo
    {
        namespace Bar { }
    }
}

And found that the following (which I gather is similar to what you're doing) doesn't work:

using OurCompany.Some.Location;

namespace OurCompany
{
    namespace This
    {
        namespace That
        {
            class BeepBoop
            {
                private void DoSomething()
                {
                    Foo.MethodName();  // No good; Foo is a namespace here.
                }
            }
        }
    }
}

...but this did:

namespace OurCompany
{
    namespace This
    {
        namespace That
        {
            using OurCompany.Some.Location;
            class BeepBoop
            {
                private void DoSomething()
                {
                    Foo.MethodName();  // Puh-wha?  This works?
                }
            }
        }
    }
}

I freely admit I don't know what's going on here. But apparently the scoping isn't as simple as "Whatever's in scope is in scope, and namespaces take priority."

4
whihathac On

I have seen this error whenever my referenced dlls are not built. It is possible that the references are not built and have some build errors. Hence both Resharper and VS are complaining about the types that are missing.

In order to fix it, I would recommend you to do the following:

  1. In the solution of 50 projects try to figure out the base projects. You can use the Project Build Order (right click sln in Solution Explorer)
  2. Disable all other projects and hit build.
  3. Now verify if the build succeeds. If build is not successful, fix the errors. If successful repeat from step 1.

I know this is tedious, but I can see this is a good way to go about fixing the overwhelming (#3000) errors you are seeing.