Разрешаем ли анализ кода «CA2000» в этом сценарии? - PullRequest
3 голосов
/ 31 июля 2011

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

Правило CA2000 гласит:

Если одноразовый объект не будет явно удален до того, как все ссылки на него выйдут из области видимости, объект будет удален через некоторое неопределенное время, когда сборщик мусора запустит финализатор объекта. Поскольку может произойти исключительное событие, которое помешает запуску финализатора объекта, объект должен быть явно удален.

Дополнительную информацию о правиле можно найти на странице, ссылки на которую приведены выше.

Код, на котором не выполняется правило:

internal Window(Game game, Control parent, string title, bool visible)
    : base(game, parent, visible, new ScreenspaceRectangle(game, Color.Black, Vector.Zero, Vector.Zero))
{
}

И описание:

CA2000: Microsoft.Reliability: в методе «Window.Window (Game, Control, string, bool)» вызовите System.IDisposable.Dispose on object «new ScreenspaceRectangle (игра, Color.Black, Vector.Zero, Vector. Ноль) до того, как все ссылки на него выйдут за рамки.

Я понимаю, что эту проблему можно решить обычным образом, используя оператор "using" вокруг создаваемого объекта, чтобы убедиться, что он всегда правильно удаляется. Но как мне решить это в этом случае?

Ответы [ 2 ]

3 голосов
/ 31 июля 2011

Предполагая, что класс Window является вашим пользовательским классом, вы должны убедиться, что конструктор базового класса хранит ссылку на ScreenspaceRectangle, если ему это требуется вне конструктора, и он реализует IDisposable и располагает экземпляр ScreenspaceRectangle в Dispose метод.

В противном случае убедитесь, что объект расположен в конструкторе базового класса.

1 голос
/ 02 августа 2011

Одно досадное ограничение c # / vb.net состоит в том, что они не позволяют обернутым в цепочку конструкторам или инициализаторам полей быть помещены в блок try-catch или try-finally. Если создание объекта Foo требует создания некоторых других объектов IDisposable, за которые Foo будет отвечать за удаление, может быть трудно гарантировать, что эти объекты будут удалены, если исключение выдается из конструктора Foo, его подтипа или его объекта. супертип. Самый простой способ справиться с этим - использовать защищенный конструктор, заключенный в фабричные методы, которые создадут экземпляр «менеджера одноразовых изделий» и передадут его через цепочку конструктора. Все, что создаст IDisposable, должно добавить его в менеджер одноразовых товаров; если конструктор выдает исключение, менеджер по расходным материалам удалит все зарегистрированные расходные материалы.

Одним из преимуществ этого подхода является то, что он позволяет выполнять очистку вложенных IDisposables кодом, который их создает, таким образом сводя к минимуму опасность того, что создание объекта и очистка кода не синхронизируются. Одно предостережение: нужно либо использовать потоковое статическое поле для отслеживания менеджера одноразовых принадлежностей, либо пропустить его через каждый шаг цепочки конструктора. Первый подход выглядит странно, но имеет то преимущество, что позволяет инициализаторам поля безопасно создавать IDisposable объекты.

...