2

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:

  1. Why am I getting nothing when I get the full name of the base type of unbound generic type? ("problem 1" in the code above)
  2. Why if the base type of my CManager instance is CEmployee, and the type of the base class of the unbound type CManager<> is CEmployee<>, and the unbound type CManager "Equals" the generic type definition of my instance, the base type of the unbound type does not "Equals" the base type of the generic type definition of my instance?? ("problem 2" in the code above)
4

1 回答 1

7

以相反的顺序:

2:因为基本类型是CEmployee<T>,不是CEmployee<>。它们是有区别的; CEmployee<>是类型定义;CEmployee<T>绑定到Tfrom 父类型。您可以通过查看IsGenericTypeDefinitionGetGenericArguments()[0]

1:因为FullName没有定义这种形式的泛型类型。这是完整记录的:

如果当前类型包含没有被特定类型替换的泛型类型参数(即 ContainsGenericParameters 属性返回 true),但该类型不是泛型类型定义(即 IsGenericTypeDefinition 属性返回 false),则该属性返回无效的。

这正是我们在“2”中讨论的内容。

于 2013-03-23T08:02:54.820 回答