Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why should the generic code compile without constraining T?

Tags:

c#

generics

The following code snippet is extracted from Example 10-11 (p. 343) from Programming C# 5.0:

public static T[] Select<T>(this CultureInfo[] cultures,
                            Func<CultureInfo, T> map)
{
    var result = new T[cultures.Length];
    for (int i = 0; i < cultures.Length; ++i)
    {
        result[i] = map(cultures[i]);
    }
    return result;
}

I can't figure out how it could get compiled without exposing any information on T by applying constraints on it. Specifically, how could the compiler know how many bytes to allocate for the array, given that T may not be a reference type, but a value type (i.e., a struct)? Also, the semantics of the assignment operation result[i] = map(cultures[i]) seems to depend on whether T is a reference type or a value type.

like image 777
Lingxi Avatar asked Apr 13 '16 15:04

Lingxi


1 Answers

There's no dependency between CultureInfo and T whatsoever. All T's are equally valid, since you handle the "conversion" using your custom Func<CultureInfo, T>.

I think you're confused about how generics work in C#. They aren't a compile-time feature (like in Java), they survive all the way to runtime. Only when you actually need a reified generic type is that type compiled, and by that point it already knows what T is.

This is of course one of the reasons why C# doesn't have Java's List<?>. There's no "common generic type", you're only "delaying" the reification of the types - once you have List<string> and List<int>, the two are entirely separate types, and only reflection tells you they come from the same generic type.

like image 117
Luaan Avatar answered Nov 16 '22 01:11

Luaan