使用块的C#中的处理顺序

时间:2010-08-10 13:43:10

标签: c# garbage-collection control-structure dispose

我真的不得不在C#中嵌套using块。它不优雅,占用了大量空间。在某些情况下,它似乎是不可避免的,因为我需要声明不同数据类型的变量,但似乎可以简化单一类型的情况。我所说的“单一类型的情况”是指几个相同类型的变量是串联声明的。这是我正在谈论的一个例子:

class Program
{
    static void Main(string[] args)
    {
        using (A a = new A("a"), b = new A("b"))
        {
        }
    }

    class A : IDisposable
    {
        string n = null;
        public A(string name)
        {
            n = name;
            Console.WriteLine(String.Format("Creating {0}", n));
        }

        public void Dispose()
        {
            Console.WriteLine(String.Format("Disposing {0}", n));
        }
    }
}

我希望这种方式发挥作用的方式是ab之前构建,ba之前展开。不幸的是,C#规范中似乎没有任何关于它应该如何发生的方向。好像微软的C#编译器就像这样对待它,因为这是运行上述程序的输出:

Creating a
Creating b
Disposing b
Disposing a

但是,我无法确保这是确定性行为。有人可以确认或反驳这个序列是确定性的吗?参考文献会很棒。显然,如果它容易破损(没有文件记录等),它可能没用,但这是一件好事。

关于deterministic disposal已经有类似的问题谈论多类型案例,我理解除了聪明的语法技巧之外没有真正的解决方案。无论如何,大多数答案都忽略了这一点。我的问题只是关于单一类型的情况以及这种处置是否具有确定性和可靠性。感谢。

2 个答案:

答案 0 :(得分:18)

来自C# spec:

using形式的using (ResourceType r1 = e1, r2 = e2, ..., rN = eN)语句完全等同于嵌套using语句的序列:”

using (ResourceType r1 = e1)
   using (ResourceType r2 = e2)
      ...
         using (ResourceType rN = eN)
            statement

所以说这是完全一致的,这似乎是公平的。

答案 1 :(得分:9)

你有什么理由不能使用多用途技巧吗?这完全是确定性的,并解决了你的问题

using (A a = new A("a"))
using (A b = new A("b")) {
    // ....
}