2010-05-14 3 views
9

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

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

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

+0

Совет. Ответственность за удаление объекта не несет метод. Это задача вызывающего. Он * является * обязанностью метода распоряжаться любыми ресурсами, которые он создал, если это необходимо. – AMissico

+0

@AMissico: «Ответственность за возврат объекта не несет ответственность за метод». К сожалению, это не так. Для некоторых методов и некоторых геттеров свойств вызывающий объект отвечает за удаление возвращаемого объекта, а для других - нет, поскольку объект кэшируется где-то и располагается где-то в другом месте. По-видимому, нет простого правила узнать, кроме проб и ошибок. – Niki

+2

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

ответ

7

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

+1

Спасибо, краткий ответ. –

3

.Dispose() никогда не будет достигнуто.

Редактировать: По-моему, нет, не следует. Вы уничтожили бы объект с этим.

3

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

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

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

+0

Я имел в виду это внутри тела функции, а не снаружи. –

+0

@ Камило Мартин - Нет смысла делать это, поскольку вызов 'Dispose' никогда не будет достигнут. Вы должны перенести вызов этой функции с помощью инструкции 'using', поэтому' Dispose' правильно вызывается, когда объект выходит за пределы области видимости. – Oded

+0

Если "return mydisposableObject;" выполняется в инструкции «using», будет выполняться .Dispose mydisposableObject между выполнением оператора return и первым шансом вызывающего пользователя использовать mydisposableObject. В большинстве случаев это сделает mydisposableObject совершенно бесполезным для вызывающего. – supercat

4

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

using (DisposeableObject myDisposableObject = gimme()) 
{ 
    //code. 
} 
+0

Ваш код приведет к ошибке компиляции, потому что вы использовали ключевое слово 'object', чтобы назвать переменную: P – prostynick

+2

Да, я тоже не думаю, что« ... код ». раздел также является синтаксисом ;-) Я все равно изменил его. –

+0

@prostynick: Это всего лишь пример кода, не нужно калечить. – AMissico

9

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

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

1

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

1

Вы можете обернуть свой код в попытке /, наконец, блок

try{ 
      int a = 0; 
      return; 
    } 
    finally{ 
      //Code here will be called after you return 
    } 
2

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

0

myDisposableObject disposableResult = new myDisposableObject();

Здесь disposableResult является ссылкой на новый объект создан. Поэтому, когда вы возвращаете эту ссылку на вызывающий метод, эта ссылка все еще указывает на созданный объект в куче. Следовательно, вы можете безопасно распоряжаться им в вызывающем методе.

0

У вас не может быть .Dispose() в возвращаемом методе. Вызывающий должен реализовать это.

7

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

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

     // ... Code to prepare disposableResult 

     return disposableResult; 
    } 
    catch(Exception) 
    { 
     if (disposableResult != null) disposableResult.Dispose(); 
     throw; 
    } 
} 
+0

+1, Интересно, не знал этого. Я начну делать это с уязвимыми объектами. –

+0

Это хорошее предложение вообще для заводов и т. Д. - но с кодом, который он опубликовал, я не уверен - и, возможно, это просто псевдо-код, но в коде, который он опубликовал, 't * create * disposableResult - это может быть общий объект и т. д. - владельцем объекта должен быть тот, кто его уничтожит ... если он создал объект (или создал объект для создания) и просто собирался настроить его и отдать его обратно, но вместо этого сделал исключение в этом процессе, то да, он должен был распоряжаться им в этом сценарии. – BrainSlugs83

1

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

+0

Добро пожаловать в SO! Этот вопрос мой от 2,5 лет назад, поэтому я могу только прокомментировать стиль написания вашего ответа: подумайте об улучшении его немного, так как в его текущем состоянии он немного похож на стену текста. У него также есть несколько опечаток, и люди здесь склонны быть разумными. Тем не менее, еще раз спасибо за то, что вы прошли мимо и ответили. –

+0

Извините за текстовую стену, просто хотел указать экземпляр, где мы уничтожим объект. – 2013-02-07 16:45:29

Смежные вопросы