调用结构的方法时,如何CLR的工作原理 [英] How CLR works when invoking a method of a struct

查看:128
本文介绍了调用结构的方法时,如何CLR的工作原理的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我觉得我认识的一类答案,只是想确认我的理解是正确的。比方说,我有一个 ClassA的和它的命名实例 A 。当 a.MethodA()调用:

I think I've known the answer for a class, just want to confirm my understanding is correct. Let's say I have a ClassA and its instance named a. When a.MethodA() is invoked:

(1)CLR找到 ClassA的的类型由 A 类型的指针的>在堆(类型已经装载到堆)

(1) CLR find the type of ClassA by the type pointer of a in the heap(the type have been loaded into the heap)

(2)找到治法的类型,如果没有找到,去其基本类型,直到对象类。

(2) Find the MethodA in the type, if not found, go to its base type, until the object class.

也许我的理解是不太precise,但我认为这是正确的basicly(纠正我,如果它是错的!)。这里谈到的问题,一个简单的结构的。

Maybe my understanding is not quite precise, but I think it's basicly correct(Correct me if it's wrong!). And here comes the question of a simple struct.

struct MyStruct
{
   public void MethodA() { }
}

我有变种X =新MYSTRUCT(); ,它的价值是在栈上,和类型 MYSTRUCT 已被加载到堆。当执行 x.MethodA(),当然没拳。如何CLR找到治法并获得IL并执行/ JIT呢?我认为,答案很可能是:(再次,纠正我,如果我错了)

I have var x = new MyStruct();, its value is on the stack, and the type of MyStruct has been loaded into the heap. When execute x.MethodA(), of course no boxing. How CLR find MethodA and get the IL and execute/JIT it? I think the answer is probably:(again, correct me if I'm wrong)

(1)我们有声明类型 X 的堆栈。 CLR发现它的类型由堆栈上的信息,并找到治法在它的类型。 - 姑且称之为 assumptionA

(1) we have the declaring type of x on the stack. CLR find its type by the info on the stack, and find MethodA in its type. -- let's call it assumptionA.

如果你告诉我,我的 assumptionA 是正确的,我会很高兴。但是,即使它是错的,它讲述了一个道理:CLR有办法找到没有拳击结构的类型

I'll be happy if you tell me my assumptionA is correct. But even it's wrong, it tells a truth: CLR has a way to find a struct's type without boxing.

现在怎么样 x.ToString() x.GetType()?我们知道,该值将被装箱,然后它会执行像一个类。但是为什么我们在这里需要拳?既然我们可以得到它的类型(assumptionA告诉我们),为什么不去它的基本类型,并找到方法(就像一个类)?为什么这里需要一个昂贵的盒子操作?

Now what about x.ToString() or x.GetType()? We know that the value will be boxed, and then it will perform like a class. But why do we need boxing here? Since we can get its type(assumptionA tells us), why not go to its base type and find the method(just like a class)? Why need an expensive box operations here?

推荐答案

AssumptionA是错误的。 C#编译器的符号表存储类型信息。静态类型信息被用在几乎所有情况下,存储在对象的动态类型中的类型检查(运算符)时才需要,铸造(经营者和实际投语法),和阵列方差,然后仅在动态类型是不知道的编译器。一装箱结构的动态类型总是静态已知,而一个类实例的动态类型是静态已知靠近实例,如果它进行类型检查(如一个条件块中(x是T) Y =(T)×; 类型是已知的,然后部分内,所以铸件不需要另一个动态支票)

AssumptionA is wrong. The C# compiler's symbol table stores type information. That static type information is used in nearly all cases, the dynamic type stored in an object is only needed during type checks (is operator), casting (as operator and actual cast syntax), and array variance, and then only when the dynamic type isn't known to the compiler. The dynamic type of an unboxed struct is always statically known, and dynamic type of a class instance is statically known near the instantiation and inside a conditional block which performed a type check (e.g. in if (x is T) y = (T)x; the type is known inside the then-part, so the cast doesn't require another dynamic check).

好了,现在因为C#编译器静态地知道了 X型,它可以做重载决议,找到的确切的治法被调用。然后,它会发出MSIL的争论推到了MSIL虚拟堆叠,并发出包含元数据的引用,该特定方法的调用指令。需要在运行时没有类型检查。

Ok, now because the C# compiler statically knows the type of x, it can do overload resolution and find the exact MethodA being called. Then it emits MSIL to push the arguments onto the MSIL virtual stack and issues a call instruction containing a metadata reference to that particular method. No type checks are needed at runtime.

有关 x.ToString(),C#编译器仍然知道它要调用确切的方法。如果的ToString 已被覆盖结构类型,它期望类型的指针于─<参数code> MYSTRUCT 的,该编译器不拳处理。如果的ToString 还没有被覆盖,编译器生成调用 Object.ToString ,它期望一个对象作为参数。为推动 X 的MSIL虚拟堆栈的正确类型需要装箱。

For x.ToString(), the C# compiler still knows the exact method it wants to call. If ToString has been overridden by the struct type, it expects a parameter of type pointer-to-MyStruct, which the compiler handles without boxing. If ToString has not been overridden, the compiler generates a call to Object.ToString, which expects an object as its parameter. To push x on the MSIL virtual stack as the correct type requires boxing.

的GetType 是当类型是已知的静态特例,编译器不会调用任何方法,它只是会从符号表的类型信息,配件的元数据引用到MSIL直接。

GetType is a special case when the type is known statically, the compiler won't call any method, it just gets the type information from the symbol table and stuffs the metadata reference into the MSIL directly.

这篇关于调用结构的方法时,如何CLR的工作原理的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆