Search code examples
c#typescompiler-errorsnamespaces

Why can't i use partly qualified namespaces during object initialization?


I suspect this is a question which has been asked many times before but i haven't found one.

I normally use fully qualified namespaces if i don't use that type often in the file or i add using namaspacename at the top of the file to be able to write new ClassName().

But what if only a part of the full namespace was added ? Why can't the compiler find the type and throws an error?

Consider following class in a nested namespace:

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

So if i now want to initialize an instance of this class, it works in following ways:

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 following doesn't 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 the compiler error:

The type or namespace name 'ns_1_1' could not be found (are you missing a using directive or an assembly reference?)

I assume because ns_1_1 is treated like a class which contains another class Foo instead of a namespace, is this correct?

I haven't found the language specification, where is this documented? Why is the compiler not smart enough to check if there's a class or namespace(-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 a problem 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

Solution

  • The documentation says:

    Create a using directive to use the types in a namespace without having to specify the namespace. A using directive does not give you access to any namespaces that are nested in the namespace you specify.

    So the using only includes the types (not the namespaces) that are defined in the specified namespace. In order to access types of nested namespace you need to specify it explicitly with a using directive as you did in your first example.