Restatement of the question
I\'m resurrecting this question because I just ran into this error again today, and I\'m still utterly confused why the
C# compiler doesn't compile when there is an ambiguity between a class and a namespace with the same name. Unfortunately you just have to namespace the class explicitly or rename the database. In your case the compiler didn't even get to the conflict, it died after resolving Foo as a namespace.
Whenever you have something like this:
using CompanyName.Foo.Models;
namespace CompanyName.Foo {
class Test {
public Foo Model { get; set; } // error CS0118: 'CompanyName.Foo' is a 'namespace' but is used like a 'type'
public Foo1 Model { get; set; } //OK
}
}
namespace CompanyName.Foo.Models {
class Foo1 {
}
class Foo {
}
}
What actually happens is every preceeding level of the namespace is implicitly imported at each level. This makes sense since the nested namespace syntax using dot is the same as nesting namespaces:
namespace CompanyName {
using CompanyName; //<--using1 - Implicit using, since we should be able to access anything within CompanyName implicitly.
namespace Foo {
using CompanyName.Foo; //<-- using2 Same as above
class Test {
public Foo Model { get; set; } //At this stage due to using1 Foo is actually CompanyName.Foo, hence the compiler error
}
}
}
So inside class Test there are two implicit usings:
using CompanyName;
using CompanyName.Foo;
Hence Foo is resolved to the namespace hence the error.
EDIT Good point. I've dug this up from MSDN:
The meaning of a namespace-or-type-name is determined as follows:
If the namespace-or-type-name consists of a single identifier:
If the namespace-or-type-name appears within the body of a class or struct declaration, then starting with that class or struct declaration and continuing with each enclosing class or struct declaration (if any), if a member with the given name exists, is accessible, and denotes a type, then the namespace-or-type-name refers to that member. Note that non-type members (constants, fields, methods, properties, indexers, operators, instance constructors, destructors, and static constructors) are ignored when determining the meaning of a namespace-or-type-name.
Otherwise, starting with the namespace in which the namespace-or-type-name occurs, continuing with each enclosing namespace (if any), and ending with the global namespace, the following steps are evaluated until an entity is located:
If the namespace contains a namespace member with the given name, then the namespace-or-type-name refers to that member and, depending on the member, is classified as a namespace or a type.
Otherwise, if the namespace has a corresponding namespace declaration enclosing the location where the namespace-or-type-name occurs, then:
If the namespace declaration contains a using-alias-directive that associates the given name with an imported namespace or type, then the namespace-or-type-name refers to that namespace or type.
Otherwise, if the namespaces imported by the using-namespace-directives of the namespace declaration contain exactly one type with the given name, then the namespace-or-type-name refers to that type.
...
(Bolding is mine) This means that when resolving Foo, matching it against CompanyName.Foo (first bold bit) happens before matching it against the using directive(second bold build).
This also happens if you generate unit tests when you have a namespace and a class with the same name. Which you should never do as explained by Eric Lippert here:
http://blogs.msdn.com/b/ericlippert/archive/2010/03/09/do-not-name-a-class-the-same-as-its-namespace-part-one.aspx