Порядок утилизации в C # с использованием блоков - PullRequest
7 голосов
/ 10 августа 2010

Меня действительно беспокоит необходимость вкладывать using блоки в C #.Это не элегантно и занимает много места.В некоторых случаях это кажется неизбежным, потому что мне нужно объявлять переменные разных типов данных, но похоже, что упрощенный случай должен быть упрощен.Под словом «случай одного типа» я подразумеваю, когда несколько переменных одного типа объявляются последовательно.Вот пример того, о чем я говорю:

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));
        }
    }
}

Я хочу, чтобы это работало так: a создается до b, а b располагается до a,К сожалению, в спецификации C # нет никаких указаний относительно того, как это должно происходить на самом деле.Похоже, что компилятор C # от Microsoft воспринимает это так, поскольку это результат работы вышеуказанной программы:

Creating a
Creating b
Disposing b
Disposing a

Однако я не могу гарантировать, что это детерминированное поведение.Может ли кто-либо подтвердить или опровергнуть идею о том, что эта последовательность является детерминированной?Ссылки были бы отличными.И, разумеется, если он подвержен поломке (недокументированный и т. Д.), Он, вероятно, бесполезен, но это полезно знать.

Уже существует аналогичный вопрос о детерминированном избавлении , в котором говорится ослучай множественного типа, и я понимаю, что там нет реального решения, кроме хитрых синтаксических приемов.Во всяком случае, большинство ответов там пропущено.Мой вопрос касается только случая одного типа и того, является ли это удаление детерминированным и надежным или нет.Спасибо.

Ответы [ 2 ]

18 голосов
/ 10 августа 2010

Из 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

Так что справедливо будет сказать, что это совершенно каменно.

9 голосов
/ 10 августа 2010

Есть ли причина, по которой вы не можете использовать трюк многократного использования?Это полностью детерминистично и решает вашу проблему

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