FxCop (/ VS2010 Code Analysis), возможно ли пометить результат метода как "ответственность вызывающих абонентов" для IDisposable? - PullRequest
3 голосов
/ 12 декабря 2011

Если я напишу следующий код:

public void Execute()
{
    var stream = new MemoryStream();
    ...
}

, тогда анализ кода помечает это как:

Предупреждение 1 CA2000: Microsoft.Reliability: В методе 'ServiceUser.Execute() ', вызовите System.IDisposable.Dispose для объекта' stream 'до того, как все ссылки на него выйдут из области видимости.C: \ Dev \ VS.NET \ DisposeTest \ DisposeTest \ ServiceUser.cs 14 DisposeTest

Однако, если я создаю фабричный шаблон, мне все равно может потребоваться избавиться от объекта, но теперь FxCopАнализ кода не жалуется. Скорее, он жалуется на фабричный метод, а не код, который его вызывает. (Я думаю, у меня был пример, который действительно жаловался на фабричный метод, но тот, который я публикую здесь, этого не делает,поэтому я вычеркнул это)

Есть ли способ, например, с использованием атрибутов, переместить ответственность объекта IDisposable из фабричного метода и вместо него на вызывающую сторону?

Возьмите этот код:

public class ServiceUser
{
    public void Execute()
    {
        var stream = StreamFactory.GetStream();
        Debug.WriteLine(stream.Length);
    }
}

public static class StreamFactory
{
    public static Stream GetStream()
    {
        return new MemoryStream();
    }
}

В этом случае предупреждений нет.Я бы хотел, чтобы FxCOP / CA все еще жаловался на мой оригинальный метод.Я по-прежнему отвечаю за обработку этого объекта.

Могу ли я как-то сообщить об этом FxCOP / CA?Например, недавно я рискнул использовать атрибуты аннотаций, которые предоставил ReSharper, чтобы сообщить информацию своего механизма анализа, которую он иначе не смог бы понять.

Поэтому я представляю что-то вроде этого:

public static class StreamFactory
{
    [return: CallerResponsibility]
    public static Stream GetStream()
    {
        return new MemoryStream();
    }
}

Или этот дизайн далеко?

1 Ответ

4 голосов
/ 15 декабря 2011

Существует разница между FxCop 10 (который поставляется с Windows 7 и .NET 4.0 SDK) и Code Analysis 2010 (который поставляется с Visual Studio Premium и выше).У Code Analysis 2010 есть набор дополнительных правил , который включает в себя значительно улучшенную версию правил IDisposable.

С Code Analysis 2010 в Visual Studio Premium фабрика не помечается (как теперь видит правило, переменная IDisposable возвращается вызывающему методу).Метод Receiving, однако, также не помечен из-за одного из исключений углового случая из правила.Существует список имен методов, которые приведут к срабатыванию правила.Если вы переименуете метод GetStream в CreateStream, правило сработает внезапно:

Warning 4   CA2000 : Microsoft.Reliability : In method 'ServiceUser.Execute()',
call System.IDisposable.Dispose on object 'stream' before all references to it are out
of scope.   BadProject\Class1.cs    14  BadProject

Мне не удалось найти список предварительных исправлений метода, которые будут работать.Я пробовал несколько и Create~, Open~ запускает правило, многие другие, которые вы можете ожидать, не сработают, включая Build~, Make~, Get~.

Кроме того, существует длинный список ошибок, окружающих это правило .Правило было изменено в Visual Studio 2010, чтобы вызвать меньше ложных срабатываний, но теперь оно иногда пропускает элементы, которые должны были быть помечены (и были бы помечены в предыдущей версии).Не было достаточно времени, чтобы исправить правила во временном интервале Visual Studio 2010 (см. Комментарии к отчету об ошибках).

С появлением новых компиляторов Roslyn Code Analysis, вероятно, увидит серьезное обновление, пока не произойдетожидаются только незначительные обновления.Текущая сборка Visual Studio Dev11 не запускается там, где вы хотите.

Итак, в заключение, ваш атрибут не сильно поможет, так как правило уже обнаруживает, что вы передаете IDisposable в качестве возвращаемого значения.Таким образом, Code Analysis знает, что не стоит утилизировать его перед возвратом.Если вы используете недокументированные правила именования, правило сработает.Возможно, атрибут мог бы расширить правила именования, но я бы предпочел, чтобы Microsoft фактически исправила фактическое правило.

Я создал ошибку подключения , запрашивающую указание по именованию в документация по правилам .

Комментарий от Microsoft:

Опубликовано Microsoft 19.01.2012 в 10:41 Здравствуйте,

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

Как вы указали в потоке stackoverflow, исторически было много проблем с надежностью этого правила, и отключение имен было внутренней деталью реализации, добавленной, чтобы попытаться уменьшить количество ложных срабатываний.Однако это не считается предписывающим руководством для того, как разработчики должны называть свои методы, оно было добавлено после обзора распространенных практик кодирования.Мы считаем, что долгосрочное исправление заключается в повышении надежности правила, а не в добавлении руководства по именованию в нашу общедоступную документацию, основанного на внутренних деталях реализации, которые будут продолжать изменяться по мере совершенствования правила.Группа анализа кода студии

...