Нулевой оператор и CA2202: не удаляйте объекты несколько раз

Имея следующее:

StringWriter sw = null;
try
{
    sw = new StringWriter();
    using (var xw = new XmlTextWriter(sw))
    {
        doc.WriteTo(xw);
        return sw.ToString();
    }
}
finally 
{
    sw?.Dispose();
}

запускает предупреждение CA2202 (не размещать объекты несколько раз) в Visual Studio 2015.

Но предупреждение не срабатывает, если изменить fianlly блок для:

finally 
{
    if (sw != null)
    {
        sw.Dispose();
    }
}

Является ли это странностью нуль-условного оператора в finally блок или что-то, или инструменты анализа в Visual Studio просто не понимают этого?

РЕДАКТИРОВАТЬ: Возможно связано: Почему Code Analysis помечает меня при использовании нулевого условного оператора с Dispose()?

1 ответ

Поскольку вы объявили xw в блоке using, при выходе из блока using будет вызван метод IDisposable для XmlTextWriter. Поскольку ваш обработчик строк используется только с XMLWriter, он также будет утилизирован сборщиком мусора (это оптимизация, чтобы избавить GC от необходимости полагаться на подсчет ссылок, чтобы определить, используется ли объект еще).

Редактировать: дополнительную информацию можно найти в этой статье MSDN.

Предупреждение "CA2202" верно.

"sw" следует удалить из "xw", если "xw" создается, или вручную, если "xw" не работает.

Поэтому после создания xw вам потребуется sw = null.

StringWriter sw = null;
try
{
    sw = new StringWriter();
    using (var xw = new XmlTextWriter(sw))
    {
        sw = null; //need to set null
        doc.WriteTo(xw);
        return sw.ToString();
    }
}
finally
{
    sw?.Dispose();
}
Другие вопросы по тегам