Why can't I use partially qualified namespaces during object initialization?

I suspect this is a question that has been asked many times, but I have not found it.

I usually use fully qualified namespaces unless I often use this type in a file or add using namaspacename to the top of the file to write new ClassName() .

But what if only part of the complete namespace were added? Why can't the compiler find the type and throw an error?

Consider the following class in a nested namespace:

 namespace ns_1 { namespace ns_1_1 { public class Foo { } } } 

So, if now I want to initialize an instance of this class, it works as follows:

 using ns_1.ns_1_1; public class Program { public Program() { // works, fully qualified namespace: var foo = new ns_1.ns_1_1.Foo(); // works, because of using ns_1.ns_1_1: foo = new Foo(); } } 

But the following does not work:

 using ns_1; public class Program { public Program() { // doesn't work even if using ns_1 was added var no_foo = new ns_1_1.Foo(); } } 

it throws a compiler error:

Could not find the type or namespace name 'ns_1_1' (are you missing the using directive or assembly reference?)

I assume that since ns_1_1 seen as a class that contains a different class Foo instead of a namespace, is this correct?

I did not find the language specification, where is this documented? Why is the compiler not smart enough to check if there is a class namespace or (-part)?


Here's another - less abstract - example of what I mean:

 using System.Data; public class Program { public Program() { using (var con = new SqlClient.SqlConnection("...")) // doesn't work { //... } } } 

Edit : Now I know why this seems very strange to me. It works without problems in VB.NET:

 Imports System.Data Public Class Program Public Sub New() Using con = New SqlClient.SqlConnection("...") ' no problem End Using End Sub End Class 
+6
source share
4 answers

The documentation says:

Create a usage directive to use types in a namespace without specifying a namespace. The using directive does not give you access to any namespace that is nested in the specified namespace.

Thus, using includes only the types (and not namespaces) that are defined in the specified namespace. To access the types of the nested namespace, you need to explicitly specify it with the using directive, as it was in the first example.

+3
source

This is documented in the standard at 3.8 Namespaces and name types , but it is a little folded to follow.

Its essence is that a link to a partial namespace is viewed only in the namespace where it occurs, and each layer goes outside. using -directives are unchecked.

In your example, ns_1_1.Foo will be found if Foo is found anywhere:

 Program.Program.ns_1_1.Foo Program.ns_1_1.Foo ns_1_1.Foo 
+1
source

Partial namespaces will only work if your current class is part of this partial namespace. Using operators is not considered for accessing types through a partial namespace.

For example, this will work because your current namespace is ns_1

 namespace ns_1 { public class Program { public Program() { var no_foo = new ns_1_1.Foo(); } } } 
+1
source

This obvious way, unfortunately, does not work, but you can do all this with aliases:

 using ns_1_1 = ns_1.ns_1_1; public class Program { public Program() { var no_foo = new ns_1_1.Foo(); } } 
+1
source

Source: https://habr.com/ru/post/973171/


All Articles