Должен ли я вызвать Dispose () внутри функции после возврата? - PullRequest
9 голосов
/ 14 мая 2010

Должен ли я вызывать .Dispose () после возврата объекта, который реализует IDisposable?

myDisposableObject Gimme() {
  //Code
  return disposableResult;
  disposableResult.Dispose();
}

Другими словами, это объект, который я возвращаю копию, или это сам объект? Спасибо:)

Ответы [ 12 ]

9 голосов
/ 14 мая 2010

Нет, ты не должен. Вы возвращаете ссылку на объект, поэтому копия не сделана. В .NET объекты никогда не копируются, если вы специально не попросите об этом.

Кроме того, вы не можете избавиться от объекта с таким кодом, даже если бы была ситуация, когда вы должны. Код после оператора return никогда не будет выполнен, и вы получите предупреждение о недоступном коде.

8 голосов
/ 14 мая 2010

Это сам объект. Не вызывайте Dispose здесь, даже если вы измените порядок, чтобы он вызывался.

7 голосов
/ 14 мая 2010

Одна вещь, о которой пока не упоминалось ни в одном из ответов, заключается в том, что вы должны утилизировать объект, если Gimme выдает исключение. Например:

MyDisposableObject Gimme() 
{
    MyDisposableObject disposableResult = null;
    try
    {
        MyDisposableObject disposableResult = ...

        // ... Code to prepare disposableResult

        return disposableResult;
    }
    catch(Exception)
    {
        if (disposableResult != null) disposableResult.Dispose();
        throw;
    }
}
4 голосов
/ 14 мая 2010

disposableResult.Dispose (); никогда не запустится, это недоступный код, так как он всегда будет возвращать строку раньше. Оберните вызов метода в используемое состояние и избавьтесь от объекта таким образом.
например,

using (DisposeableObject myDisposableObject = gimme())
{
    //code.
}
3 голосов
/ 14 мая 2010

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

using(var mydisposableObject = new Gimme())
{
   // code
}

При создании вашего кода вы возвращаете одноразовый объект, поэтому вызов Dispose никогда не будет достигнут.

3 голосов
/ 14 мая 2010

В любом случае .Dispose() никогда не будет достигнуто.

Редактировать: На мой взгляд, нет, вы не должны.Вы уничтожите Объект этим.

2 голосов
/ 14 мая 2010

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

1 голос
/ 05 февраля 2013

Я согласен, не удаляйте этот объект, он передается по ссылке. Есть особый случай, который я могу вспомнить, когда порождаю объекты, когда класс оборачивает другой класс и распределяет объекты: Вы не хотите, чтобы объект, выдаваемый, был ссылаться на тот же самый, чтобы вы клонировали или передали копию объекта и уничтожили оригинал, однако, если оригинал является стандартным изображением для всех видов этого типа, объект не создается специально для каждого вызова, и вы ожидаете появления нескольких номеров в в течение короткого периода времени вы можете захотеть сохранить его, так как вы можете создать новый объект из этого изображения, не создавая его снова. Я бы предпочел заблокировать все свойства этого объекта только для чтения и привести объект только для чтения к чтению / записи. объект, который можно использовать в реальном мире. Объект не должен запускать какие-либо потоки внутри себя, когда он передается в качестве копии значения или клона, однако, если он является многопоточным, то прекрасно передать его ссылку, если ссылка является отношением 1: 1, если у вас есть несколько указателей. для объекта, который одновременно читает и записывает этот объект «бегущего изображения», вы можете столкнуться с коллизиями, когда значение не было безопасно сохранено, и следующий пингер запрашивает и назначает это же значение. Одна вещь, которую мы в огромной степени не обсуждали, когда я учился в школе, это объектные состояния. Объектно-ориентированные принципы были укоренились, но понимание того, почему они были созданы, всегда занимало время ... Я дал понять, я изучил объектно-ориентированный стиль, а затем перешел к более процедурным стилям.

1 голос
/ 14 мая 2010

Вы можете заключить код в блок try / finally

    try{
            int a = 0;
            return;
    }
    finally{
            //Code here will be called after you return
    }
1 голос
/ 14 мая 2010

Эта строка: disposableResult.Dispose(); не будет выполнена. Возвращаемая «вещь» не является копией объекта. Это ссылка на объект, поэтому вызывающая сторона будет манипулировать объектом, созданным в Gimme, и он (вызывающая сторона) должен помнить, чтобы уничтожить объект.

...