The documentation of the instance property Type.IsConstructedGenericType
is unclear or misleading.
I tried the following code to find the actual behavior of this and related properties:
// create list of types to use later in a Dictionary<,>
var li = new List<Type>();
// two concrete types:
li.Add(typeof(int));
li.Add(typeof(string));
// the two type parameters from Dictionary<,>
li.Add(typeof(Dictionary<,>).GetGenericArguments()[0]);
li.Add(typeof(Dictionary<,>).GetGenericArguments()[1]);
// two unrelated type parameters
li.Add(typeof(Func<,,,>).GetGenericArguments()[1]);
li.Add(typeof(EventHandler<>).GetGenericArguments()[0]);
// run through all possibilities
foreach (var first in li)
{
foreach (var second in li)
{
var t = typeof(Dictionary<,>).MakeGenericType(first, second);
Console.WriteLine(t);
Console.WriteLine(t.IsGenericTypeDefinition);
Console.WriteLine(t.IsConstructedGenericType);
Console.WriteLine(t.ContainsGenericParameters);
}
}
The code runs through a Cartesian product consisting of 36 types t
.
Results: For 32 types (all but the 4 combinations Dictionary<int, int>
, Dictionary<int, string>
, Dictionary<string, int>
, Dictionary<string, string>
), the value of ContainsGenericParameters
was true.
For 35 types, IsGenericTypeDefinition
was false while IsConstructedGenericType
was true. For the last type, namely (unsurprisingly):
System.Collections.Generic.Dictionary`2[TKey,TValue]
the IsGenericTypeDefinition
was true and IsConstructedGenericType
was false.
Can I conclude that, for a generic type, the value of IsConstructedGenericType
is always the opposite (negation) of IsGenericTypeDefinition
?
(The documentation seems to claim that IsConstructedGenericType
is instead the opposite of ContainsGenericParameters
, but we clearly exhibited a lot of counterexamples to that.)
Yes this is correct. Assuming that the
Type
in question is a generic type, exactly one ofIsGenericTypeDefinition
orIsConstructedGenericType
is true. We can easily from the reference source forRuntimeType
(which is the concrete implementation ofType
you get when you doGetType()
ortypeof
) why this is the case: