using-statement何时在其结构上加上参数,何时是struct? [英] When does a using-statement box its argument, when it's a struct?

查看:66
本文介绍了using-statement何时在其结构上加上参数,何时是struct?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对以下代码有疑问:

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 from Test() 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:

前段时间,伊恩·格里菲思(Ian Griffiths)写道 他的TimedLock类的改进 他把它从一堂课变成了 一个结构.此更改导致 实现的值类型 IDisposable.我有一个na的问题 在当时我的脑海中 我很快就忘记了.这 问题不是那个例子 致电Dispose时,键入get boxed?

A while ago Ian Griffiths wrote about an improvement to his TimedLock class in which he changed it from a class to a struct. This change resulted in a value type that implements IDisposable. I had a nagging question in the back of my mind at the time that I quickly forgot about. The question is wouldn’t instances of that type get boxed when calling Dispose?

还有哦,不!不再是TimedLock!:

约翰·桑兹(John Sands)指出了 我在最近的博客中显示的代码 在没有锁的情况下使用超时 放弃了大多数的便利 C#的lock关键字.

John Sands points out a flaw in the code I showed in a recent blog for using timeouts on locks without abandoning most of the convenience of C#'s lock keyword .

这篇关于using-statement何时在其结构上加上参数,何时是struct?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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