构造类的C#型对象
我已经读到引用类型都使用相同的构造类: 泛型对于引用类型的工作方式有所不同。第一次使用任何引用类型构造泛型类型时,运行时将创建一个专门的泛型类型,用对象引用替换MSIL中的参数。然后,每当构造的类型以引用类型作为参数进行实例化时,不管它是什么类型,运行时都会重用先前创建的泛型类型的专用版本。这是可能的,因为所有引用的大小都相同。() 但是,在基于相同泛型和不同类型参数的构造对象上调用GetType()时,会收到两种不同的类型。其中A和B都是类,而RefType是泛型:构造类的C#型对象,c#,generics,types,C#,Generics,Types,我已经读到引用类型都使用相同的构造类: 泛型对于引用类型的工作方式有所不同。第一次使用任何引用类型构造泛型类型时,运行时将创建一个专门的泛型类型,用对象引用替换MSIL中的参数。然后,每当构造的类型以引用类型作为参数进行实例化时,不管它是什么类型,运行时都会重用先前创建的泛型类型的专用版本。这是可能的,因为所有引用的大小都相同。() 但是,在基于相同泛型和不同类型参数的构造对象上调用GetType()时,会收到两种不同的类型。其中A和B都是类,而RefType是泛型: RefType<A&
RefType<A> a = new RefType<A>();
RefType<B> b = new RefType<B>();
Console.WriteLine("a type is "+a.GetType());
Console.WriteLine("b type is "+b.GetType());
这是否意味着即使没有“真正的”专门化实例化,CLR也会为不同的构造类型处理类型对象的创建?
有没有办法直接查看CLR生成和未生成的内容
这是否意味着即使没有“真正的”专门化实例化,CLR也会为不同的构造类型处理类型对象的创建
对。考虑运行时类型检查是语言的一个重要部分。
var x = new List<string>() as List<object>;
您将看到
G.f
、G.f
、G.f
和G.f
具有相同的方法句柄,但G.f
、G.f
、G.f
都具有不同的方法句柄。甚至连G.f
和G.f
都没有共享实现。类型对象在高抽象级别上提供类型信息,并告诉您逻辑上的类型是什么,而泛型的实现是一个低级细节,您不应该依赖它。实现细节总是可以更改的
T
和T
是两种不同的类型,因此它们必须由不同的Type
对象来描述。这是因为Type
对象不仅生成T
的信息,还生成a
或B
的信息,即泛型类型参数的信息。这两种类型共享相同的代码库这一事实没有什么区别
Type
对象属于API。您可以在代码中使用此信息。Type
类将来可能会被扩展以反映该语言的新特性,但这不是一个突破性的变化
当您想要编写高效的代码时,最好了解实现细节。一些低级工具(O/R映射器、代码编织器等);但是,有时确实需要依赖于实现细节。类型仍然非常不同。本文试图说的是(它可以以一种更清晰的方式做到这一点,而且还有许多其他糟糕的编写方法)用于实现这些类型的实际代码可以为所有引用类型的实例化共享。不过,这是一个程序员通常不太关心的实现细节。您需要连接一个调试器并检查jitted代码才能看到这一点;我不确定在C#级别是否有任何方法来验证这一点。有用的建议,但不是问题的答案。有时,您需要深入了解实现细节。为了完整性(或作为读者的练习),您可以验证G
是否与其他引用类型共享其实现,而G
既不与引用类型共享实现,也不与G
@jeroenmoster共享实现感谢您的建议,补充道,以及其他一些案例。
var x = new List<string>() as List<object>;
class G<T> { public void f() { } }
class A { }
class B { }
struct C { }
struct D { }
enum E : int { }
static void Main(string[] args)
{
Console.WriteLine(typeof(G<object>).GetMethod("f").MethodHandle.Value);
Console.WriteLine(typeof(G<string>).GetMethod("f").MethodHandle.Value);
Console.WriteLine(typeof(G<A>).GetMethod("f").MethodHandle.Value);
Console.WriteLine(typeof(G<B>).GetMethod("f").MethodHandle.Value);
Console.WriteLine(typeof(G<C>).GetMethod("f").MethodHandle.Value);
Console.WriteLine(typeof(G<D>).GetMethod("f").MethodHandle.Value);
Console.WriteLine(typeof(G<E>).GetMethod("f").MethodHandle.Value);
Console.WriteLine(typeof(G<int>).GetMethod("f").MethodHandle.Value);
}