问题描述
我对以下代码有疑问:
using System;
namespace ConsoleApplication2
{
public struct Disposable : IDisposable
{
public void Dispose() { }
}
class Program
{
static void Main(string[] args)
{
using (Test()) { }
}
static Disposable Test()
{
return new Disposable();
}
}
}
我的问题是:
- 从
Test()
框返回的Disposable
结构上的使用声明是否为结构? - 我如何自己找到答案?
- Will the using-statement that operates on the
Disposable
struct, returned fromTest()
box the struct, or not? - How can I find the answer myself?
为了发现自己,我检查了以上代码产生的IL,以下是Main(...)
方法的IL:
To try to find out myself, I inspected the IL produced by the above code, and here's the IL for the Main(...)
method:
.method private hidebysig static void Main(string[] args) cil managed
{
.entrypoint
.maxstack 1
.locals init (
[0] valuetype ConsoleApplication2.Disposable CS$3$0000)
L_0000: call valuetype ConsoleApplication2.Disposable ConsoleApplication2.Program::Test()
L_0005: stloc.0
L_0006: leave.s L_0016
L_0008: ldloca.s CS$3$0000
L_000a: constrained ConsoleApplication2.Disposable
L_0010: callvirt instance void [mscorlib]System.IDisposable::Dispose()
L_0015: endfinally
L_0016: ret
.try L_0006 to L_0008 finally handler L_0008 to L_0016
}
我怀疑在L_0010
上对虚拟方法的调用会引入装箱操作,但实际的box
指令不在此处.
I suspect the call to the virtual method there, on L_0010
will introduce a boxing operation, but the actual box
instruction is not here.
我要问的原因是前一段时间,大概是1-2年,我在网上看到有人评论的使用状态的优化".在这种情况下,使用状态语句被用作对象上的短期锁定的语法,在该方法中获取了该锁定,并返回了一个结构,该结构在被处置时将释放该锁定,代码如下:
The reason I'm asking is that a while ago, probably 1-2 years, I saw online an "optimization" of the using-statement someone commented on. The case was where the using-statement was used as syntax for a short-time lock on an object, where the lock was acquired in the method, and a struct was returned, which when disposed of, would release the lock, code like this:
using (LockTheObject())
{
// use the object
}
注释是,通过将LockTheObject
方法的返回类型从IDisposable
更改为实际使用的结构,可以避免装箱.
and the comment was that by changing the return type of the LockTheObject
method from IDisposable
to the actual struct used, boxing was avoided.
但是我想知道这是真的还是真的.
But I'm wondering if this is true, or still true.
有人能指出我正确的方向吗?如果要查看框操作,我必须检查运行时汇编代码,请给我看一个查找内容的示例,我精通汇编代码,所以这不是问题,但没有任何问题当我看着那一个时看着我.
Can anyone point me in the right direction? If, in order to see the box operation, I'll have to inspect the runtime assembly code, please show me an example of what to look for, I'm well versed in assembly code so that's not a problem, but nothing jumped out at me when I looked at that either.
推荐答案
看来,放在using
语句中的任何值类型都不会被装箱.这似乎是C#优化,因为仅当在using
语句中而不是在其他任何上下文中实现IDisposable
的值类型时,才省略装箱.
It appears as though any value type that gets put in a using
statement will not be boxed. This appears to be a C# optimization as boxing is only omitted when a value type that implements IDisposable
is in a using
statement, not in any other context.
有关更多信息,请参见使用语句和一次性值类型 :
For more info please see The Using Statement And Disposable Value Types:
这篇关于using-statement何时在其结构上加上参数,何时是struct?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!