Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/268.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
构造类的C#型对象_C#_Generics_Types - Fatal编程技术网

构造类的C#型对象

构造类的C#型对象,c#,generics,types,C#,Generics,Types,我已经读到引用类型都使用相同的构造类: 泛型对于引用类型的工作方式有所不同。第一次使用任何引用类型构造泛型类型时,运行时将创建一个专门的泛型类型,用对象引用替换MSIL中的参数。然后,每当构造的类型以引用类型作为参数进行实例化时,不管它是什么类型,运行时都会重用先前创建的泛型类型的专用版本。这是可能的,因为所有引用的大小都相同。() 但是,在基于相同泛型和不同类型参数的构造对象上调用GetType()时,会收到两种不同的类型。其中A和B都是类,而RefType是泛型: RefType<A&

我已经读到引用类型都使用相同的构造类:

泛型对于引用类型的工作方式有所不同。第一次使用任何引用类型构造泛型类型时,运行时将创建一个专门的泛型类型,用对象引用替换MSIL中的参数。然后,每当构造的类型以引用类型作为参数进行实例化时,不管它是什么类型,运行时都会重用先前创建的泛型类型的专用版本。这是可能的,因为所有引用的大小都相同。()

但是,在基于相同泛型和不同类型参数的构造对象上调用GetType()时,会收到两种不同的类型。其中A和B都是类,而RefType是泛型:

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);
}