Нужно ли мне использовать несколько операторов using?

Из соображений практичности оба урока одноразовые.

Я понимаю, что делает блок using. Но я не уверен в том, как его можно или нужно использовать.

Например, это правильно?

using (MyClass myClass = new MyClass(params))
{
     myClass.name = "Steve";

     SecondClass myClassSecond = new SecondClass(params);
     myClassSecond.name = "George";
     myClassSecond.msg = "Hello Man in the Yellow Hat";
}

Утилизируются ли оба вышеуказанных класса?

Или мне нужно и то, и другое внутри оператора using?

using (MyClass myClass = new MyClass(params))
{
     myClass.name = "Steve";

     using (SecondClass myClassSecond = new SecondClass(params))
     {
          myClassSecond.name = "George";
          myClassSecond.msg = "Hello Man in the Yellow Hat";
     }
}

Верно ли приведенное выше или есть лучший способ использовать несколько операторов using?


person James Wilson    schedule 12.06.2013    source источник
comment
Реализуют ли эти классы IDisposable? Это необходимо (и причина) using.   -  person Hans Kesting    schedule 12.06.2013
comment
Это зависит от вашей реализации MyClass и SecondClass, а также от того, когда вам нужно, чтобы эти объекты были Dispos()ed.   -  person Richard JP Le Guen    schedule 12.06.2013
comment
обман? stackoverflow.com/ questions / 567138 /   -  person saj    schedule 12.06.2013
comment
Связанные / dupes: stackoverflow.com/questions/3544758/ stackoverflow.com/questions/2284938/ stackoverflow .com / questions / 16861329 /   -  person user7116    schedule 12.06.2013
comment
Оба будут одноразовыми, да. Извините за отсутствие деталей.   -  person James Wilson    schedule 12.06.2013
comment
В вашем первом примере конец блока using не будет волшебным образом избавиться от объекта myClassSecond только потому, что он выходит за пределы области видимости. Удаляется только объект, указанный в скобках using. Так что это неправильно. Вы должны вложить операторы using, как в последнем примере.   -  person Jeppe Stig Nielsen    schedule 12.06.2013


Ответы (9)


  • Оператор using позволяет программисту указать, когда объекты, использующие ресурсы, должны их освободить.
  • Объект, предоставленный оператору using, должен реализовывать интерфейс IDisposable.
  • Этот интерфейс предоставляет метод Dispose, который должен высвободить ресурсы объекта.

Вот пример, показывающий использование оператора using:

using System;
//Object of this class will be given to using hence IDisposable
class C : IDisposable        
{
    public void UseLimitedResource()
    {
        Console.WriteLine("Using limited resource...");
    }

    //Dispose() Method
    void IDisposable.Dispose()
    {
        Console.WriteLine("Disposing limited resource.");
    }
}

class Program
{
    static void Main()
    {
        using (C c = new C())  //Object of Class defined above
        {
            c.UseLimitedResource();
            //Object automatically disposed before closing.
        }                            
        Console.WriteLine("Now outside using statement.");
        Console.ReadLine();
    }
}

Из оператора using можно выйти, если:

  • достигнут конец оператора using или
  • если генерируется исключение и управление покидает блок операторов до конца оператора.

Какой правильный метод?

Как вы говорите,

Оба класса из соображений практичности одноразовые.

., тогда вам подойдет второй подход. это:

using (MyClass myClass = new MyClass(params))
{
     myClass.name = "Steve";

     using (SecondClass myClassSecond = new SecondClass(params))
     {
          myClassSecond.name = "George";
          myClassSecond.msg = "Hello Man in the Yellow Hat";
     }
}
person Bhushan Firake    schedule 12.06.2013

Использование блоков удобно, когда вы работаете со всем, что реализует IDisposable интерфейс. MSDN:

[Оператор using] Определяет область, за пределами которой объект или объекты будут удалены.

Таким образом, это фактически эквивалент

IDisposable resource = new Whatever();
try {
    // whatever
}
finally {
    resource.Dispose();
}

Основные преимущества using: он автоматически удаляет объект при выходе из блока using, поэтому (1) вы не забудете это сделать и (2) он выполняет очистку в случае исключения.

Краткие правила:

  • Каждый раз, когда вы открываете соединение с файлом / базой данных или создаете экземпляр класса, который требует какой-либо очистки, делайте это в блоке using.
  • Если время жизни объекта должно расширить область действия метода - обернуть его в класс, реализовать IDisposable в этом классе, создать экземпляр ресурса в конструкторе, очистить в Dispose.
person J0HN    schedule 12.06.2013

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

К вашему сведению, я предпочитаю этот стиль для размещения нескольких объектов в одном блоке, так как я считаю его более читаемым.

using (MyClass myClass = new MyClass(params))
using (SecondClass myClassSecond = new SecondClass(params))     
{
     myClassSecond.name = "George";
     myClassSecond.msg = "Hello Man in the Yellow Hat";     
}

Оба usings используют одну и ту же область видимости и Dispose в обратном порядке объявления.

person dkackman    schedule 12.06.2013
comment
Это то, что я искал, спасибо. Я не был уверен, помещал ли все в один, используя блок, избавляющийся от всего этого, или каждый элемент нужно было завернуть в свой собственный одноразовый пузырек. Оба предмета действительно одноразовые, я пренебрегал этой информацией. Еще раз спасибо. - person James Wilson; 12.06.2013

Блок using не удаляет автоматически дочерние объекты, реализующие IDisposable. Вы должны обернуть внутренние предметы одноразового использования блоками, если хотите, чтобы они были утилизированы. Однако у вас есть несколько разных вариантов для этого.

Вы можете вложить несколько блоков using, и они оцениваются от самого внутреннего до самого внешнего. Есть способ сделать это лучше, но следующий пример работает:

using (MyClass myClass = new MyClass(parameters))
{
     using (SecondClass myClassSecond = new SecondClass(parameters))
     {
          myClassSecond.name = "George";
          myClassSecond.msg = "Hello Man in the Yellow Hat";
     }
}

Если объявления являются последовательными и вам не нужно ничего делать между ними, следующий синтаксис будет более лаконичным:

using (MyClass myClass = new MyClass(parameters))
using (SecondClass myClassSecond = new SecondClass(parameters))
{
    myClassSecond.name = "George";
    myClassSecond.msg = "Hello Man in the Yellow Hat";
}

Если вам нужно сделать что-то между объявлениями, то ваш последний пример верен:

using (MyClass myClass = new MyClass(parameters))
{
     myClass.name = "Steve";

     using (SecondClass myClassSecond = new SecondClass(parameters))
     {
          myClassSecond.name = "George";
          myClassSecond.msg = "Hello Man in the Yellow Hat";
     }
}
person DanilF    schedule 12.06.2013

Мое практическое правило ... если он реализует idisposable, я использую блок using.

Всегда лучше перестраховаться, чем сожалеть.

Чтобы ответить на ваш вопрос, я бы выбрал второй вариант.

person Smeegs    schedule 12.06.2013

Простой ответ: если у класса есть метод удаления, используйте using.

http://msdn.microsoft.com/en-us/library/system.io.streamreader.aspx

Если нет, то в этом нет необходимости.

http://msdn.microsoft.com/en-us/library/system.random.aspx

Мне всегда хотелось, чтобы в документации MSDN это было больше бросается в глаза. В конце концов, это классы, которые реализуют IDisposable, но на самом деле мне нужен какой-то гигантский значок на странице, который каким-то образом говорит. «Обратите внимание, манекен! Вы должны справиться с этим сами!

person Matthew Vines    schedule 12.06.2013

Блок using - это чисто синтаксически простой способ работы с объектами IDisposable. Если вы понимаете, что делает using, тогда вы должны понимать, как это можно и нужно использовать.

См. Этот вопрос, чтобы узнать, на что именно переведен блок using: Использование использования в C #

person foolmoron    schedule 12.06.2013

Это зависит от того, что это за классы и как они распоряжаются используемыми ресурсами. Оператор using по сути то же самое, что и блок try/finally (без catch), который распределяет свои ресурсы в блоке finally (вызывая .Dispose() для рассматриваемого объекта).

Итак, во-первых, если рассматриваемый класс не реализует IDisposable, тогда это спорный вопрос, вы не можете использовать его в блоке using в этом случае. Если он действительно реализует IDisposable, то, скорее всего, он делает это по какой-то причине и .Dispose() следует вызывать для этого объекта, когда вы закончите с ним. В таких случаях разумно заключить его в using блок, чтобы гарантировать удаление. (Ну, "гарантия" в той степени, в какой будет выполнен блок finally. Это обычно так, если не случилось чего-то гораздо худшего.)

person David    schedule 12.06.2013

Мне нравится реализовывать IDisposable в создаваемых мной классах, если они используют много ресурсов или если я создаю его как оболочку для обработки файлов или сетевых ресурсов.

В объектах класса, которые я использую, я думаю, что важно вызывать с блоком using, если рассматриваемый объект открывает файлы, создает сетевые соединения и т. Д.

Некоторые разработчики напишут класс, реализующий IDisposable, чтобы они могли поместить свой код в более чистый блок using, но я думаю, что это злоупотребляет причиной создания чего-то, что является Disposable.

person jp2code    schedule 12.06.2013