泛型的低级实现

时间:2016-03-11 16:50:15

标签: c# generics

如果我有这个:

class Pair<T> {}

class Animal {}
class Human {}

然后:

Pair<Animal> a = new Pair<Animal>();
Pair<Human> h = new Pair<Human>();

我读到CLR只创建了一次Pair的专用版本 T替换为object。创建h后,它会重用该版本。

但我不明白这意味着什么。当objectAnimal类型且Human类型时,它如何以类型安全的方式知道?

这是什么意思&#34; 重复使用&#34;?

2 个答案:

答案 0 :(得分:1)

不 - 那是Java如何做到的 - 它会在编译时使用正确的类型进行检查,但在幕后,一切都只是Pair<object>

C#要好得多,因为它每次都会创建一个真正的新类型。为什么这种方法更好?因为您可以使用反射在运行时找到类型(您可以在Java中执行此操作)

如果您生成IL,您可以看到这一点 - 您可以看到唯一类型:

IL_0000:  nop         
IL_0001:  newobj      UserQuery<UserQuery+Animal>+Pair`1..ctor
IL_0006:  stloc.0     // a
IL_0007:  newobj      UserQuery<UserQuery+Human>+Pair`1..ctor
IL_000C:  stloc.1     // h
IL_000D:  ret         

Pair`1..ctor:
IL_0000:  ldarg.0     
IL_0001:  call        System.Object..ctor
IL_0006:  ret         

Animal..ctor:
IL_0000:  ldarg.0     
IL_0001:  call        System.Object..ctor
IL_0006:  ret         

Human..ctor:
IL_0000:  ldarg.0     
IL_0001:  call        System.Object..ctor
IL_0006:  ret         

答案 1 :(得分:0)

  

当对象是Animal类型以及何时是Human类型时,它如何以类型安全的方式知道?

你不能,至少不能来自Pair类。现在根据类型声明知道Pair类的外部

class Pair<T> {
    public T Value {get; set;}  // the compiler has no idea what the type of `T` is at compile-time
}

Pair<Animal> a = new Pair<Animal>();
a.Value = new Animal();   // here the compiler knows that `Value` is an `Animal` based on the declared type of `a`.