2013-03-23 80 views
2

在C#中使用泛型时,我被奇怪的行为难倒了。考虑以下代码:未绑定泛型类型的C#基类不可用?

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 


    } 
} 

输出是

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 

我难倒,为什么基类中的未绑定的泛型类型是不完全可用:

  1. 为什么我收到什么时候我得到基地的全名 类型的未绑定的泛型? (在上面的代码“问题1”)
  2. 为什么如果我的CManager实例的基本类型是 CEmployee,和基类中的未结合的 类型的CManager <类型>是CEmployee <>,和未结合的类型CManager “等于”我的实例的泛型类型定义,未绑定类型的基类型 不等于泛型的类型定义的基类型 我的实例? (在上面的代码 “问题2”)

回答

7

在相反的顺序:

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

1:因为这种通用类型形式的FullName未定义。这是fully documented

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

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

+0

确实!这就解释了为什么如果#2你把BaseGenericTypeDefinition放在BaseType之后,它确实有效。 – Mishax 2013-03-23 08:14:56