Search code examples
c#using

C#: given type alias X, why I can't use List<X> in a definition of another type alias?


C# compiler (Visual Studio 2019, C# 7.3) does not like using an aliased type as a generic argument of another aliased type. I looked in C# language spec, and there seems to be no explicit prohibition against that. Is it a bug or a feature?

// C#
using System;
using System.Collections.Generic;

namespace Foo
{
    using IntPair = Tuple<int,int>;
    using IntPairList = List<IntPair>; // does not compile: IntPair is not found
    
    class Bar
    {
        static List<IntPair> list; // compiles OK
    }
}

Solution

  • According to the section in the spec about using directives in general (emphasis mine),

    The scope of a using_directive extends over the namespace_member_declarations of its immediately containing compilation unit or namespace body. The scope of a using_directive specifically does not include its peer using_directives. Thus, peer using_directives do not affect each other, and the order in which they are written is insignificant.

    In short, you cannot make use of the effect of other usings in the same "scope" (I'm using this word very loosely here), when writing a using directive.

    More examples:

    using System;
    // using IntPair = Tuple<int,int>; // Not OK, can't use the effect of "using System;" here!
    using IntPair = System.Tuple<int,int>; // OK
    
    using IntPair = System.Tuple<int,int>;
    namespace Foo
    {
        // OK, "IntPair" is introduced in a parent "scope", not the Foo namespace
        using IntPairList = List<IntPair>;
    }