Consider the following short code snippet.
namespace B
{
public class Foo
{
public string Text
{
get { return GetType().FullName; }
}
}
}
namespace A.B
{
public class Foo
{
public string Text
{
get { return GetType().FullName; }
}
}
}
Get familiar with example #1 first.
using B;
namespace A.C
{
public static class Program
{
public static void Main()
{
Console.WriteLine(new Foo().Text);
}
}
}
Now consider example #2.
namespace A.C
{
using B; // Notice the placement here.
public static class Program
{
public static void Main()
{
Console.WriteLine(new Foo().Text);
}
}
}
There is nothing terribly peculiar about example #1. However, things get interesting with example #2. It is imperative that you pay close attention to all identifiers used in the examples. As a fun exercise try to guess what happens without plugging this into the compiler. I will not reveal the answer here because 1) it is easy enough to try yourself and 2) I do not want to ruin the fun.
Will the program:
- not compile
- display B.Foo
- display A.B.Foo
The question…Where in the C# specification is this behavior described?
I did take a look at section 3.7 in the C# 4.0 specification and especially bullet #2, but I do not think that explains the behavior. If anything it almost makes me think the compiler is behaving contradictory to the specification.
The first example prints “B.Foo”, the second example prints “A.B.Foo”. This is because in the second example the
using B;directive is enclosed inside theA.Cnamespace.Why does it use
A.Brather thanB?Because namespace lookups follow the same rules as type name qualification lookups. Section 3.8 of the C# spec.
Basically, when the
usingdirective is processed by the compiler , the symbolBis looked for in theA.Cnamespace. Not finding it, it’s looked for in theAnamespace. Because it’s found there as a sub-namespace ofA, it selects that namespace and doesn’t go to the global namespace to find theBnamespace.Edit:
As @P.Brian.Mackey suggests, you can get to the
Bnamespace withusing global::B;.