GetGenericTypeDefinition返回不同的类型

时间:2014-05-22 10:15:52

标签: c# inheritance types type-systems

鉴于我有以下类型

interface IMyInterface<T> { }
class MyClass<T> : IMyInterface<T> { }

以下5行怎么会产生相同的结果呢?

var type1 = typeof(IMyInterface<>);
var type2 = typeof(IMyInterface<object>).GetGenericTypeDefinition();
var type3 = typeof(MyClass<>).GetInterfaces().Single();
var type4 = typeof(MyClass<object>).GetInterfaces().Single().GetGenericTypeDefinition();
var type5 = typeof(MyClass<object>).GetGenericTypeDefinition().GetInterfaces().Single();

type1,type2&amp; type4是相同的

type3&amp; type5是相同的

2 个答案:

答案 0 :(得分:4)

在3和5的情况下,不同的类型;来自{{1}的IMyInterface<SpecificT>其中SpecificT泛型类型参数(不是实际已知的,而是参数本身) } - 即它是依赖的。

这与MyClass<T>中的完全免费(独立)T不同,后者是1,2和4提供的。

如果你重命名Ts,那就更明显了:

IMyInterface<T>

现在检查每个interface IMyInterface<TA> { } class MyClass<TB> : IMyInterface<TB> { } 。对于1,2和4,它是.GetGenericArguments().Single().Name。对于3和5,它是TA

答案 1 :(得分:0)

除了Marc Gravell之外,还有一些额外的工作要指出差异:

using System;
using System.Linq;

namespace test {
  class Program {
    interface IMyInterface<T> { }
    class MyClass<T> : IMyInterface<T> { }

    private static void Print(Type xType) {
      unsafe {
        fixed (char* c = xType.Name) {
          long lAddress = (long)c;
          Console.WriteLine(lAddress);
        }
      }
    } //

    static void Main(string[] args) {
      Type type1 = typeof(IMyInterface<>);
      Type type2 = typeof(IMyInterface<object>).GetGenericTypeDefinition();
      Type type3 = typeof(MyClass<>).GetInterfaces().Single();
      Type type4 = typeof(MyClass<object>).GetInterfaces().Single().GetGenericTypeDefinition();
      Type type5 = typeof(MyClass<object>).GetGenericTypeDefinition().GetInterfaces().Single();

      Print(type1); // 34060364
      Print(type2); // 34060364
      Print(type3); // 34062812
      Print(type4); // 34060364
      Print(type5); // 34062812     

      // therfore:
      // type1 == type2 == type4
      // and
      // type3 == type5

      Console.WriteLine("type1 == type2  " + type1.Equals(type2)); // true
      Console.WriteLine("type1 == type4  " + type1.Equals(type4)); // true
      Console.WriteLine("type2 == type4  " + type2.Equals(type4)); // true
      Console.WriteLine("type3 == type5  " + type3.Equals(type5)); // true

      Console.WriteLine("type1 == type5  " + type1.Equals(type5)); // false
      Console.WriteLine("type2 == type5  " + type2.Equals(type5)); // false
      Console.WriteLine("type4 == type5  " + type4.Equals(type5)); // false
      Console.WriteLine("type3 == type4  " + type3.Equals(type4)); // false
      Console.WriteLine("type1 == type3  " + type1.Equals(type3)); // false
      Console.WriteLine("type2 == type3  " + type2.Equals(type3)); // false

      // the names are the same, but the objects are not
      Console.WriteLine(type1.Name.ToString());
      Console.WriteLine(type2.Name.ToString());
      Console.WriteLine(type3.Name.ToString());
      Console.WriteLine(type4.Name.ToString());
      Console.WriteLine(type5.Name.ToString());            

 /* example output:
38778956
38778956
38781404
38778956
38781404
type1 == type2  True
type1 == type4  True
type2 == type4  True
type3 == type5  True
type1 == type5  False
type2 == type5  False
type4 == type5  False
type3 == type4  False
type1 == type3  False
type2 == type3  False
IMyInterface`1
IMyInterface`1
IMyInterface`1
IMyInterface`1
IMyInterface`1
*/

      Console.ReadLine();
    }
  }
}

http://csharphardcoreprogramming.wordpress.com/2014/01/02/reflection-basics-advanced/