использование инициализатора объекта генерирует предупреждение CA 2000

Следующий код генерирует предупреждение CA2000:

Myclass myclass = null;
try
{
   myclass = new Myclass { Name = "a name" };
}
finally
{
   if (myclass != null)
   {
      myclass.Dispose();
   }
}

я нашел некоторые темы с той же проблемой, и как я понимаю, проблема в том, что компилятор генерирует для конструктора временную переменную, и для этой переменной я не вызываю Dispose().

var tmp = new MyClass();
tmp.Name = "a name";
myclass = tmp:

поэтому мой вопрос в том, есть ли решение с использованием инициализатора объекта, которое не генерирует предупреждение ca2000.

заранее спасибо.


person rhe1980    schedule 05.01.2012    source источник
comment
Я также задавался вопросом, почему вы вручную записываете оператор using, но даже там генерируется такое же предупреждение.   -  person Damien_The_Unbeliever    schedule 05.01.2012
comment
См. также этот вопрос   -  person Damien_The_Unbeliever    schedule 05.01.2012
comment
Я видел эту тему (и некоторые другие с такой же проблемой). но во всех этих темах я не нашел решения с использованием инициализаторов объектов.   -  person rhe1980    schedule 05.01.2012
comment
Это потому, что все ответы сводятся к тому, что это невозможно сделать, потому что способ реализации инициализаторов объектов означает, что вы можете утечь объект IDisposable.   -  person Damien_The_Unbeliever    schedule 05.01.2012


Ответы (1)


Как указывает Дэмиен в комментариях, предупреждение FxCop действительно, поскольку компилятор C# создает экземпляр IDisposable в скрытой переменной temp, и когда во время инициализации одного из свойств возникает исключение, этот экземпляр не будет удален.

При хорошем дизайне API это не будет проблемой, так как ресурсы (вещи, которые реализуют IDisposable) должны содержать метод Open (или Begin, Start, что угодно) (в соответствии с Руководством по проектированию фреймворка) и не должны утекать до вызова Open . Это правило создано по той же причине, по которой вы столкнулись: чтобы предотвратить утечку во время инициализации. FDG были написаны до C# 3.0, но та же проблема возникает, когда исключение вызывается из конструктора этого экземпляра (что всегда может произойти из-за асинхронных исключений, таких как прерывание потока). Поскольку ссылка на экземпляр в этот момент не публикуется, никто не может избавиться от этого экземпляра. Поэтому не рекомендуется инициализировать базовые ресурсы во время построения.

Таким образом, вы можете спокойно отбросить это предупреждение, когда Myclass содержит какой-то метод Open и когда вы не инициализируете его значениями, которые сами реализуют IDisposable. В других случаях следует вернуться к следующему:

var myclass = new MyClass();

try
{
    myclass.Name = "a name";
}
finally
{
    myclass.Dispose();
}
person Steven    schedule 05.01.2012