Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

If A<T1,T2> is a template for actual type, then why is typeof(A<,>) allowed?

Tags:

c#

generics

class Program
{
    static void Main(string[] args)
    {
        Type t = typeof(A<,>);
        Console.WriteLine(typeof(A<,>)); // prints A'2[T1,T2]
    }    
}

class A<T1,T2>
{

}

As far as I know, generic type A<T1, T2> is not an actual type, but rather a blueprint/template for an actual type, so why does typeof accept it as a parameter (since as far as I know, typeof accepts as parameter actual types)?

Thank you

like image 270
flockofcode Avatar asked Jul 10 '10 19:07

flockofcode


3 Answers

In reflection the unconstructed generic type, say C<> is conflated with the instance type C<T>.

This is perhaps less than theoretically pure; I think of these as very different entities. I think of one as the symbol "C with one type parameter" and the other as a compile time type C<T>. In code, C<> and C<T> are not synonyms for each other; you can make a field of the latter type if T is in scope, but you cannot ever make a field of the former type.

That the reflection library gives you the type of the instance type when you ask for the unconstructed type is not all bad though. What would you do with the unconstructed type? There's nothing you really can do with it. But with the instance type, you can say "substitute int for T" in here.

The real benefit of getting C<T> when you ask for typeof(C<>) is that this always gives you the unconstructed type. Compare:

class C<T>
{
    public static Type CT() { return typeof(C<T>); }
    public static Type JustC() { return typeof(C<>); }
}

When you call CT, what are you going to call it on? There's no type C<T> to call CT on. You can call C<int>.CT in which case you'll get back C<int>, not C<T>. The only way to get the type C<> constructed with T is to ask for typeof(C<>).

Does that make sense?

I haven't yet covered reflection ( I have a vague idea of what it is )

Reflection is simply the library of code that allows you to get information about your code in the code itself. "typeof" gives you a Type object which you can then "reflect" upon to find out information about the type.

I'm not sure I understand what you mean by "even when T is not in scope"

The way I said it was confusing. I've rephrased it.

like image 83
Eric Lippert Avatar answered Oct 27 '22 17:10

Eric Lippert


It is accepted because it is a generic type.

It is an open generic type (where they type parameters have not been specified), but a type none the less.

See the discussion here (What exactly is an “open generic type”).

And on MSDN (typeof):

The typeof operator can also be used on open generic types.

like image 20
Oded Avatar answered Oct 27 '22 15:10

Oded


Because A<T1, T2> is an open generic, which the documentation explicitly says it supports.

like image 23
John Weldon Avatar answered Oct 27 '22 16:10

John Weldon