对值类型调用方法是否会导致 .NET 中装箱?
我刚刚参与了 Stack Overflow 问题.NET 中的所有内容都是对象吗?< /a>。
一位发帖者(在已接受答案的评论中)似乎认为对值类型执行方法调用会导致装箱。 他向我指出装箱和拆箱(C# 编程指南),它没有准确指定我们正在描述的用例。
我不是一个相信单一来源的人,所以我只是想获得有关该问题的进一步反馈。 我的直觉是没有拳击,但我的直觉确实很糟糕。 :D
进一步详细说明:
我使用的示例是:
int x = 5;
string s = x.ToString(); // Boxing??
如果所讨论的结构覆盖从对象继承的方法(如此处接受的答案所述),则装箱不会发生。
但是,如果结构体不重写该方法,则会先执行“约束”CIL 命令到 callvirt。 根据文档,操作码。约束场,这会导致装箱:
如果 thisType 是值类型并且 thisType 没有实现方法 然后 ptr 被取消引用、装箱,并且 作为“this”指针传递给 callvirt方法指令。
I was just participating in Stack Overflow question Is everything in .NET an object?.
And one poster (in comments of accepted answer) seemed to think that performing a method call on a value type resulted in boxing. He pointed me to Boxing and Unboxing (C# Programming Guide) which doesn't exactly specify the use case we're describing.
I'm not one to trust a single source, so I just wanted to get further feedback on the question. My intuition is that there is no boxing but my intuition does suck. :D
To further elaborate:
The example I used was:
int x = 5;
string s = x.ToString(); // Boxing??
Boxing does not occur if the struct in question overrides the method inherited from the object as the accepted answer here states.
However if the struct doesn't override the method, a "constrain" CIL command is executed prior to a callvirt. According to the documentation, OpCodes.Constrained Field, this results in boxing:
If thisType is a value type and
thisType does not implement method
then ptr is dereferenced, boxed, and
passed as the 'this' pointer to the
callvirt method instruction.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
这是您的代码的 IL:
所以本例中的答案是否定的。
Here's the IL for your code:
So the answer in this case is no.
在您给出的情况下,答案是否定的,正如底座指出的那样。
但是,如果您通过接口指针调用方法,则会出现这种情况。
考虑代码:
那么
不会导致装箱:
但是,这会:
In the case you have given the answer is no, as plinth pointed out.
However, it will if you call a method through an interface pointer.
Consider the code:
Then
Does not result in boxing:
However, this does:
@ggf31316
我已经为你检查了 ToString。Int32 确实覆盖了 ToString,所以我创建了一个不覆盖 ToString 的结构。我使用了 .NET Reflector 以确保该结构不会以某种方式神奇地覆盖 ToString(),但事实并非如此,
因此代码如下:
MSIL(通过 ILDASM) 是这样的:
现在,尽管没有发生拳击调用,如果您检查 < a href="http://msdn.microsoft.com/en-us/library/system.reflection.emit.opcodes.constrained.aspx" rel="nofollow noreferrer">有关 constrained + 调用 virt 的文档,你会发现它表明拳击确实发生了oOo
引用:
@ggf31316
I have checked ToString for you. Int32 does override ToString, so I made a struct that doesn't. I used .NET Reflector to ensure that the struct wasn't somehow magically overriding ToString(), and it wasn't.
So the code was like this:
And the MSIL (via ILDASM) for the Main method is this:
Now, despite no boxing call taking place, if you check the documentation about a constrained + a call virt, you will find it states that boxing DOES take place. oOo
Quote:
我相信,如果结构不重写方法,调用 ToString、Equals 和 Gethashcode 会导致装箱。
I believe that calling ToString, Equals and Gethashcode result in boxing if the structure does not override the methods.