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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With