Будет ли использование работать на нуле? - PullRequest
13 голосов
/ 02 апреля 2009

Будет ли работать следующий код, если ресурс не реализует IDisposable?

  T resource = new T();
  using (resource as IDisposable)
  {
     ...
  }

Ответы [ 8 ]

16 голосов
/ 02 апреля 2009

Да. Оператор using проверяет, предоставляется ли ему null, и избегает попытки вызвать Dispose, если это так.

Из раздела 8.13 спецификации C # 3:

Оператор использования переводится на три части: приобретение, использование и удаление. Использование ресурса неявно заключено в оператор try это включает в себя, наконец, пункт. это наконец, пункт располагает ресурс. Если нулевой ресурс приобрел, то нет вызова для утилизации сделано, и не исключение не выбрасывается.

10 голосов
/ 02 апреля 2009

Да, это будет работать, проверьте этот текущий тест:

[TestMethod]
public void TestMethod8()
{
    using (new MyClass() as IDisposable)
    {
    }
}
public class MyClass { }

Он работает без проблем. Если соответствующий класс реализует IDisposable, он вызовет его, если нет, он все равно будет работать / работать:).

Обновление: Как уже говорили другие, мне также интересно, какую пользу вы хотите ему дать. Я предполагаю, что у вас есть что-то вроде фабрики, которая может получать экземпляры из разных классов, которые могут быть или не быть одноразовыми

2 голосов
/ 02 апреля 2009

При тестировании кода он, по-видимому, не приводит к ошибкам во время компиляции или во время выполнения.

Из определения языка (см. Раздел 8.13): -

Если нулевой ресурс получен, то нет вызова утилизации, и нет исключение.

Если тип не может быть преобразован в IDisposible, оператор as преобразует ресурс в null, а код, инкапсулированный в блоке using, будет работать идеально, ведя себя точно так же, как если бы вы не включили его в блок using.

Короче говоря, ответ на ваш вопрос - да.

2 голосов
/ 02 апреля 2009

Это должно работать нормально, даже если это не «правильный» подход к утилизации ресурсов. Статуя using является просто синтаксическим сахаром для

IDisposable o = ...;

try
{
  // ...
}
finally
{
  if (o != null)
    o.Dispose(true);
}

Так что, если o никогда не реализовано IDisposable, оно будет нулевым в операторе using и попытается вызвать Dispose для него.

1 голос
/ 02 апреля 2009

Это может быть полезно, когда тип явно реализует IDisposable, и в этом случае метод Dispose не доступен напрямую для типа, если только тип не приведен к IDisposable. Использование «as» делает безопасное приведение и гарантирует, что вызов Dispose , В большинстве случаев, когда тип явно реализует IDisposable, он предоставляет такие методы, как «Close», который, в свою очередь, вызывает Dispose

1 голос
/ 02 апреля 2009

Какая польза от этого? В чем преимущество? В чем выгода?

С помощью оператора using будет вызываться метод Dispose, но если ваш объект не реализует IDisposable, я не вижу смысла в этом? Он будет работать (как, например, он не будет генерировать исключения во время выполнения и скомпилируется), я только что протестировал его здесь, но ...

С записанным вами кодом вы даже не сможете использовать ресурс как IDisposable ...

1 голос
/ 02 апреля 2009

Если под "будет ли это работать" вы имеете в виду, получите ли вы ошибку во время выполнения? Нет, не будешь.

0 голосов
/ 02 апреля 2009

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

http://aspnetresources.com/blog/the_very_handy_using_statement.aspx

...