C# GetGenericTypeDefinition返回不同的类型

C# GetGenericTypeDefinition返回不同的类型,c#,inheritance,types,type-systems,C#,Inheritance,Types,Type Systems,鉴于我有以下类型 interface IMyInterface<T> { } class MyClass<T> : IMyInterface<T> { } 接口IMyInterface{} 类MyClass:IMyInterface{} 为什么以下5行不能产生相同的结果 var type1 = typeof(IMyInterface<>); var type2 = typeof(IMyInterface<object>).GetGe

鉴于我有以下类型

interface IMyInterface<T> { }
class MyClass<T> : IMyInterface<T> { }
接口IMyInterface{}
类MyClass:IMyInterface{}
为什么以下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();
var type1=typeof(IMyInterface);
var type2=typeof(IMyInterface).GetGenericTypeDefinition();
var type3=typeof(MyClass).GetInterfaces().Single();
var type4=typeof(MyClass).GetInterfaces().Single().GetGenericTypeDefinition();
var type5=typeof(MyClass).GetGenericTypeDefinition().GetInterfaces().Single();
类型1、类型2和类型4是相同的


类型3和类型5是相同的

在3和5的情况下,它是不同的类型;它是
IMyInterface
,其中
specific
MyClass
中的泛型类型参数(不是实际已知值,而是参数本身)——即它是依赖的

这不同于
IMyInterface
中的完全免费(独立)的
T
,这是1、2和4提供的

如果重命名Ts,它将变得更加明显:

interface IMyInterface<TA> { }
class MyClass<TB> : IMyInterface<TB> { }
接口IMyInterface{}
类MyClass:IMyInterface{}

现在,针对每个参数检查
.GetGenericArguments().Single().Name
。对于1、2和4,它是
TA
。对于3和5,它是
TB

除了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();
    }
  }
}
使用系统;
使用System.Linq;
名称空间测试{
班级计划{
接口IMyInterface{}
类MyClass:IMyInterface{}
专用静态无效打印(xType类型){
不安全{
已修复(char*c=xType.Name){
长lAddress=(长)c;
控制台。WriteLine(lAddress);
}
}
} //
静态void Main(字符串[]参数){
类型1=类型of(IMyInterface);
Type type2=typeof(IMyInterface).GetGenericTypeDefinition();
Type type3=typeof(MyClass).GetInterfaces().Single();
Type type4=typeof(MyClass).GetInterfaces().Single().GetGenericTypeDefinition();
Type type5=typeof(MyClass).GetGenericTypeDefinition().GetInterfaces().Single();
打印(类型1);//34060364
打印(类型2);//34060364
打印(类型3);//34062812
打印(类型4);//34060364
打印(打字5);//34062812
//因此:
//类型1==类型2==类型4
//及
//类型3==类型5
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
//名称相同,但对象不同
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());
/*示例输出:
38778956
38778956
38781404
38778956
38781404
type1==type2 True
type1==type4 True
type2==type4 True
type3==type5 True
type1==type5 False
类型2==类型5错误
type4==type5 False
type3==type4 False
type1==type3 False
类型2==类型3错误
IMyInterface`1
IMyInterface`1
IMyInterface`1
IMyInterface`1
IMyInterface`1
*/
Console.ReadLine();
}
}
}

在你的第二行文字中,你说它们不一样。在最后一行,你告诉我们所有五个变量都一样?它们都可能返回接口的类型,因为这是您要求它返回的类型。.在type3中,您应该得到一个实例化的泛型接口类型,其中T绑定到MyClass的T。它们具有相同的名称是巧合。好的,这是一种“通过”的方法吗<代码>类型(MyClass).GetInterfaces().Single()。???==字体(IMyInterface)