Когда использовать оператор Using - PullRequest
4 голосов
/ 21 марта 2011

Я думаю, что я могу неправильно использовать выражение Using. Как лучше написать это?

Dim x As New Serialization.XmlSerializer( ... )
Using file As New FileStream(myFile, FileMode.Create)
   Using writer As XmlWriter = XmlTextWriter.Create(file)
      x.Serialize(writer, myCollection)
   End Using
End Using

Я читал, что вы должны использовать блок using только для объектов, которые имеют .Dispose() (т.е. реализует IDisposable), поэтому я думаю, что не должно быть использования on on " писатель ", но вместо writer.Close() в конце. Но у «файла» есть и .Dispose(), и .Close(), так что мне использовать? using или file.Close()?

Примечание. Я использую XmlWriter, потому что могу настроить вывод. Я удалил настройки здесь, хотя.

Ответы [ 5 ]

11 голосов
/ 21 марта 2011

Оба FileStream и XmlWriter реализуют IDisposable - код правильный. На самом деле компилятор, вероятно, не позволил бы вам сделать это, если бы это было неправильно. Если нет общедоступного .Dispose(), то оно должно использовать явную реализацию интерфейса - но это не меняет вашей ответственности за вызов .Dispose(). Для интереса, в C # вы можете избежать постоянно увеличивающегося вложения / отступа, то есть

using(...a...)
using(...b...)
using(...c...)
{
   ...
}

но, по сути, ваш текущий код верен.

3 голосов
/ 21 марта 2011

Это действительно сбивает с толку и является предметом многих споров. Это реализация метода Dispose ():

Public Sub Dispose()
    Me.Close
End Sub

Другими словами, вызов Dispose () делает точно такой же , что и вызов Close (). Вы определенно хотите воспользоваться преимуществом использования оператора здесь.

2 голосов
/ 21 марта 2011

Да, проблема .Close и .Dispose немного прискорбна.

Это (было?) Официальное руководство по РС. Метод Close называется Псевдоним, специфичный для домена .

И, как подсказывает слово Псевдоним, вы можете предположить, что они делают то же самое. Обычно Close просто вызывает Dispose.

Блок Using ... End Using будет компилироваться только со ссылкой, которая является IDisposable (имеет .Dispose)


Общий совет:

  • Если у класса есть .Dispose, используйте блок Using
  • Using - это просто сокращение для Try ... Finally, и вы можете вернуться к этому. Но
  • Не изобретайте, пытаясь объединить или сэкономить несколько блоков
  • Когда вложение углубляется (> 3..5), исключите дополнительный метод.
1 голос
/ 21 марта 2011

Я бы хотел сделать и то и другое, но это может быть потому, что я немного старомоден.Если я открыл файл (который у вас есть), я явно закрою его.Будет ли метод Dispose выполнять чистое закрытие, зависит от реализации объекта, а не от клиента.Но, поскольку объект все еще реализует IDisposable, вам все равно нужно вызвать его.

1 голос
/ 21 марта 2011

Ваш код выглядит правильно.Обратите внимание, что вы получите ошибку во время компиляции, если попытаетесь использовать using для типа данных, который не поддерживает IDispose.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...