I am stumped by weird behavior while working with generics in C#. Consider this code:
class CEmployee<T> { }
class CManager<T> : CEmployee<T> { }
class Program
{
static void Main(string[] args)
{
CManager<String> cemp = new CManager<String>();
Console.WriteLine(cemp.GetType());
Console.WriteLine(cemp.GetType().FullName);
Console.WriteLine(cemp.GetType().BaseType);
Console.WriteLine(cemp.GetType().BaseType.FullName);
Console.WriteLine(1);
Console.WriteLine(cemp.GetType().GetGenericTypeDefinition());
Console.WriteLine(cemp.GetType().GetGenericTypeDefinition().FullName);
Console.WriteLine(cemp.GetType().GetGenericTypeDefinition().BaseType);
Console.WriteLine(cemp.GetType().GetGenericTypeDefinition().BaseType.FullName); // Problem 1
Console.WriteLine(2);
Console.WriteLine(typeof(CManager<>));
Console.WriteLine(typeof(CManager<>).FullName);
Console.WriteLine(typeof(CManager<>).BaseType);
Console.WriteLine(typeof(CManager<>).BaseType.FullName); // Problem 1
Console.WriteLine(3);
Console.WriteLine(typeof(CManager<>).Equals(cemp.GetType().GetGenericTypeDefinition()));
Console.WriteLine(typeof(CEmployee<>).Equals(cemp.GetType().GetGenericTypeDefinition().BaseType)); // Problem 2
}
}
The output is
ConsoleApplication1.CManager`1[System.String]
ConsoleApplication1.CManager`1[[System.String, mscorlib, Version=4.0.0.0, Culture=neutr
ConsoleApplication1.CEmployee`1[System.String]
ConsoleApplication1.CEmployee`1[[System.String, mscorlib, Version=4.0.0.0, Culture=neut
1
ConsoleApplication1.CManager`1[T]
ConsoleApplication1.CManager`1
ConsoleApplication1.CEmployee`1[T]
2
ConsoleApplication1.CManager`1[T]
ConsoleApplication1.CManager`1
ConsoleApplication1.CEmployee`1[T]
3
True
False
I am stumped as to why the base class of the unbound generic type is not fully usable:
In reverse order:
2: because the base type is CEmployee<T>, not CEmployee<>. There is a difference; CEmployee<> is the type-definition; CEmployee<T> is bound to the T from the parent type. You can see this by looking at IsGenericTypeDefinition and GetGenericArguments()[0]
1: because the FullName of this form of generic type is not defined. This is fully documented:
If the current type contains generic type parameters that have not been replaced by specific types (that is, the ContainsGenericParameters property returns true), but the type is not a generic type definition (that is, the IsGenericTypeDefinition property returns false), this property returns null.
which is exactly what we discussed in "2".
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