Odd .NET Namespace Scoping Causes Compile-Time Exception
This isn’t really a bug in the .NET compilers, but it sure is an interesting namespace scoping issue that could easily be encountered. If this teaches you anything, be it that you should never name a nested namespace level the same name as one of its parents in the hierarchy.
In C#
First here’s the Compile Time Exception that I was getting:
The type or namespace name ‘Data’ does not exist in namespace ‘MyApp.Data.MyApp’ (are you missing an assembly reference?)
At first I was like “What do you mean namespace ‘Data’ doesn’t exist in ‘MyApp.Data’?”
Here’s the C# code that causes this exception:
namespace MyApp.Data
{
public partial class Person
{
public string Name { get; set; }
}
}
namespace MyApp.Data.MyApp
{
public partial class Billy : MyApp.Data.Person
{
}
}
If you are familiar with scoping of namespaces in .NET then you probably can see what the issue is. Remember, I has this issue in a large solution with multiple projects and it wasn’t as straight forward as this. This example is the most basic example that will raise this exception.
Basically, since the ‘Billy’ class is within the ‘MyApp.Data.MyApp’ namespace, all references to the ‘MyApp’ namespace will be scoped to the nested ‘MyApp’ instead of the root. So, as a consequence, the ‘MyApp.Data.Person’ object doesn’t exist because the compiler is really looking for ‘MyApp.Data.MyApp.Data.Person’.
How about VB.NET?
Another thing to point out is that I also tested this in VB.NET, and the VB.NET compiler gives a similar compile-time exception message for the same ‘MyApp.Data.Person’ reference within the ‘Billy’ class. Here’s VB.NET’s message:
Type ‘MyApp.Data.Person’ is not defined
Here’s the VB.NET code:
Namespace MyApp.Data
Public Class Person
End Class
End Namespace
Namespace MyApp.Data.MyApp
Public Class Test
Public Sub New()
Dim person = New MyApp.Data.Person()
End Sub
End Class
End Namespace
Conclusion
You may assume, as I did at first, that the compiler should just fall back to the ‘MyApp’ root namespace if it can’t find the type within the nested namespace. This assumption was completely incorrect, and after thinking it over, the compilers response does make sense.
I actually never ran into this before, so I thought I would share.
Related Posts
-
C#: Read Text and JSON File Contents into Variable in Memory
18 Jun 2024 -
How to Cast an Int to an Enum in C#
17 Jun 2024 -
C#: How to Enumerate over Enum values and names
03 May 2024