【发布时间】:2011-03-31 02:46:29
【问题描述】:
我想我已经知道了一堂课的答案,只是想确认我的理解是正确的。假设我有一个ClassA 及其实例名为a。当a.MethodA() 被调用时:
(1)CLR通过堆中a的类型指针找到ClassA的类型(该类型已加载到堆中)
(2)在类型中找到MethodA,如果没有找到,就去它的基类型,直到object类。
也许我的理解不是很准确,但我认为它基本上是正确的(如果有错请纠正我!)。这里是一个简单的struct的问题。
struct MyStruct
{
public void MethodA() { }
}
我有var x = new MyStruct();,它的值在栈上,MyStruct的类型已经加载到堆中。执行x.MethodA()时,当然没有装箱。 CLR 如何找到MethodA 并获取 IL 并执行/JIT?我认为答案可能是:(再次,如果我错了,请纠正我)
(1) 我们在堆栈上有x 的声明类型。 CLR 通过栈上的信息找到它的类型,并在它的类型中找到MethodA。 -- 我们称之为assumptionA。
如果你告诉我我的assumptionA 是正确的,我会很高兴。但即使它是错误的,它也说明了一个事实:CLR 有一种方法可以在不装箱的情况下找到结构的类型。
现在x.ToString() 或x.GetType() 呢?我们知道该值将被装箱,然后它将像一个类一样执行。但是为什么我们在这里需要拳击呢?既然我们可以得到它的类型(假设 A 告诉我们),为什么不去它的基类型并找到方法(就像一个类一样)?为什么这里需要一个昂贵的盒子操作?
【问题讨论】:
-
@Danny Chen,结构并不总是分配在堆栈上。它仅在以下情况下才在堆栈上分配:1) 作为值作为参数传递给方法,2) 不是闭包的一部分,以及 3) 不是大对象。否则,它仍然在堆上分配。
-
@Stephen Chung:感谢您的提示。但在这种情况下,它是,对吧?
-
好吧,如果它是一个局部变量,它就在堆栈上,不是很大(似乎不是)并且没有在闭包中捕获(所以这取决于你在这个块中的代码是否包含一个 lambda)。
-
@Stephen:你确定大型结构是在堆上分配的吗?我不相信大小会有所不同...
-
@Mehrdad - 对象 > 85KB 始终分配在与常规堆分开的“大对象堆”上。 > 85KB 的 AFAIK 结构也属于这一类,但您需要努力构建如此大的结构......
标签: c# .net clr value-type il