Короткий ответ: CA2000 сломан и вряд ли будет исправлен в ближайшее время. См this bug report, который почти точно на ваш вопрос:
Предупреждение CA2000, в частности, это правило, имеет проблемы, и что мы не сможем это исправить в его нынешнем виде.
Чем дольше ответ, что получение CA2000 права является трудно. В прошлых версиях Visual Studio, особенно в 2010 году, ложные предупреждения CA2000 запускались повсюду, и вы ничего не могли сделать, чтобы заставить их уйти. Поиск переполнения стека для любого из десятков вопросов об этом.
Даже в тех случаях, когда вы могли устранить предупреждение, обходной путь был почти хуже, чем просто оставить его на месте. Проблема в том, что у вас есть не хочу, чтобы объект был удален до того, как он покинет область действия фабричного метода. Кроме того, вы делаете - , если он выдает исключение. В этом случае возвращаемое значение метода теряется, и вызывающий объект не имеет возможности распоряжаться объектом для себя.
К сожалению, попытка понять это означает выполнение анализа потока программ скомпилированного ИЛ, чтобы определить, может ли какой-либо путь кода (включая исключительные) пропустить объект. Конечным результатом был почти любой случай, когда вы попытались вернуть IDisposable
из метода, приведет к ошибке.
Microsoft ответила на это, делая две вещи:
- Cranking вниз по чувствительности CA2000, так что это срабатывает только на наиболее очевидные из случаев. Это кажется разумным, так как очевидные случаи, такие как ваша первая строка, скорее всего будут ошибками, чем более неясными, и их легче исправить.
- Принимает CA2000 из своих рекомендуемых правил анализа кода; обратите внимание, что в их наборе правил «Расширенная правильность» больше нет CA2000.
Наряду с переписыванием компилятора Roslyn появляется возможность для таких инструментов, как FxCop, провести анализ исходного уровня, который может быть проще в этом случае получить. Между тем, общий консенсус, просто выключите CA2000.
В случае, если вы любопытны, немного тестирования, кажется, подтверждает, что текущее правило (2013) CA только пожары если локально содержали, локально построен экземпляр IDisposable
капель из области видимости. IOW, объект не может оставить метод, в котором вы его используете new
, или CA игнорирует его. Это заставляет меня думать, что CA просто не копает в вызовы методов для его анализа. Помимо попыток заставить замолчать ложные срабатывания, он также может быть частью общей попытки ускорить процесс CA, вырезав некоторые дорогие чеки, которые, по моему мнению, произошли в период с 2010 по 2012 год?
Если добавить немного в вашем примере, вы можете увидеть очевидную картину, какие из них получить предупреждение:
class Program
{
public static void Main()
{
new Disposable(); // CA2000
IDisposable x;
MakeDisposable(out x);
Test();
}
public static Disposable Test()
{
IDisposable z;
var x = MakeDisposable(out z);
var y = new Disposable(); // CA2000
return x;
}
private static Disposable MakeDisposable(out IDisposable result)
{
result = new Disposable();
new Disposable(); // CA2000
return new Disposable();
}
}
Попробуйте переименовать свой метод Make создать и посмотреть, если это делает разницу. –
также ... какую версию Visual Studio и/или FxCop вы используете? –
Я попытался импровизировать что-то полезное для вас, но, пожалуйста, попробуйте сделать более описательный заголовок в следующий раз. – quetzalcoatl