1

I have a class that's name is the same as the namespace is is contained within:

Class File ReadModel.cs

namespace App.Core.ReadModel
{
    public class ReadModel 
    {
    } 
} 

Class File MyClass.cs

using App.Core.ReadModel; // this does not work

namespace Something
{
    // using App.Core.ReadModel (Works if I un-comment)

    public class MyClass
    {            
       public void test()
        {
            var x = new ReadModel(); 
        }
    }
}

When trying to instantiate the class, even when trying to add a using directive at the top, the compiler is still unable to resolve the class. HOWEVER, if I put the using statements nested within the namespace, it works fine.

Can someone pls explain why this works? This is a new feature I've just discovered.

The error is: App.Core.ReadModel is a namespace but is used like a type

Marco
  • 2,453
  • 3
  • 25
  • 35

2 Answers2

3

Edit again:

Nicholas answered your revised question very nicely. Please see his answer:

Visual Studio unable to resolve class name unless using nested using block

EDIT:

Using have to be at the top of the file. Move the using above the first namespace.

Example:

namespace App.Core.ReadModel
{
    public class ReadModel
    {
    }
}

using App.Core.ReadModel; // cannot be placed here. Must be at top of file.

namespace App
{
    public class Program
    {
        public static Main()
        {
            var obj = new ReadModel();
        }
    }
}

Original Answer (irrelevant to question):

Option 1: Rename Namespace

namespace App.Core.IO
{
    public class ReadModel
    {
    }
}

Option 2: Use an Alias

using MyReadModel = App.Core.ReadModel.ReadModel;

public class Program
{
    public static void Main()
    {
        var obj = new MyReadModel();
    }
}

Option 3: Qualify Type Name

public class Program
{
    public static void Main()
    {
        var obj = new App.Core.ReadModel.ReadModel();
    }
}
Community
  • 1
  • 1
cwharris
  • 17,835
  • 4
  • 44
  • 64
  • yeah, i get the other ways to resolve it, but that does not explain why nesting the using statement within the outer namespace works. – Marco Nov 03 '11 at 20:26
  • Without seeing the specific error message it would be hard to tell. I haven't personally been able to reproduce the problem. – rossipedia Nov 03 '11 at 20:33
  • Just re-prod it. His using is after a namespace. It needs to be before the namespace. – cwharris Nov 03 '11 at 20:33
  • when the using is at the verytop of a file, before the namespace, it does not work. if you nest the using statement within the namespace, it works. – Marco Nov 03 '11 at 20:36
  • You must edit your question to represent which code is contained in what files. The code you presented has an error which would be solved with me answer. – cwharris Nov 03 '11 at 20:37
  • @Marco, I wasn't able to get back till now, but it looks like Nicholas answered your question nicely. – cwharris Nov 03 '11 at 21:15
3

The difference between

using System  ;
using Foo.Bar ;

namespace My.Widget.Tools
{
  public class MySpecialTool
  {
    ...
  }
}

and

using System ;

namespace My.Widget.Tools
{
  using Foo.Bar ;

  public class MySpecialTool
  {
    ...
  }
}

is that in the first case, the directive using Foo.Bar ; causes the objects in the namespace Foo.Bar to be imported into the unnamed (global) namespace for the compilation unit. In the second case, the using directive imports the objects in the namespace Foo.Bar into the namespace My.Widget.Tools.

The difference has to do with search order in resolving unqualified references.

Unqualified references are resolved by first searching within the enclosing named namespace. If the reference is not resolved, then the unnamed (global) namespace for the compilation unit is searched.

Consider the case where the above namespace Foo.Bar contains a visible class that conflicts with a class contained in the System namespace.

In the first case, where the Foo.Bar namespace has been loading into the global namespace, you'll get an error regarding an ambiguous reference if you try to reference the conflicting object: it will search the enclosing namespace first, on not finding it, it will then look into the global namespace and find multiple objects and whine.

In the second case, the enclosing namespace is searched first, on finding an object of the desired name, the unqualified reference is resolved and the compiler is happy: no conflict.

Note that you can coerce the search order to the global namespace by qualifying an object reference with the global:: prefix. You can also define your own aliases with the using directive, either for a namespace:

using io = System.IO ;

or for a type:

using IntList = System.Collections.Generic.List<int> ;

the caveat with defining an alias for the namespace is that you then have to use the alias to resolve a reference. An alias defined for a type just gives you a [perhaps] shorthand way of naming the type. Probably more useful for generics than anything else. I don't see a lot of value in doing something like:

using Row = System.Data.DataRow ;

outside of writing obfuscated C#.

See also this question: Should 'using' statements be inside or outside the namespace?

§16 of ISO/IEC 23270:2006 (Information technology -- Programming languages -- C#) will tell you far more than you ever wanted to know about namespaces and using directives.

See also this MSDN piece on namespace aliases: http://msdn.microsoft.com/en-us/library/c3ay4x3d(v=vs.80).aspx

Community
  • 1
  • 1
Nicholas Carey
  • 71,308
  • 16
  • 93
  • 135
  • I still don't understand why Marco's code didn't work. Does ReadModel conflict with a class in another namespace which he failed to tell us he's also using? – Igby Largeman Nov 03 '11 at 21:26
  • Then how did this answer your question? This is about name conflicts. It seems irrelevant to your problem. – Igby Largeman Nov 04 '11 at 14:09
  • Well, since he hasn't really told us the specifics of the problem... :D It would be nice to know (A) the specific error message or exception he's getting, (B) actual source code that will repro the problem, (C) what version of the CLR runtime he's building against, (D) what version of Visual Studio or Mono dev environment he's using ... VS2005 is likely to be considerably different VS2010. – Nicholas Carey Nov 04 '11 at 16:50