CA2000 Передача ссылки на объект на базовый конструктор в C #

StackOverflow https://stackoverflow.com/questions/2687398

Вопрос

Я получаю предупреждение, когда я запускаю код через утилиту анализа кода Visual Studio, которая не уверен, как разрешать. Возможно, кто-то здесь столкнулся с подобной проблемой, решил ее, и готов поделиться своим пониманием.

Я программирую пользовательскую окрашенную клетку, используемую в управлении DataGridView. Код напоминает:

public class DataGridViewMyCustomColumn : DataGridViewColumn
{
    public DataGridViewMyCustomColumn() : base(new DataGridViewMyCustomCell())
    {
    }

Это генерирует следующее предупреждение:

Ca2000: Microsoft.Reality: в методе «datagridviewmycustomcumumn.datagridviewmycustomcolumns) system.

Я понимаю, что предупреждает меня datagridviewmycustomcell (или класс, который он наследует от) реализует интерфейс iDisposable, и метод dispose () следует вызывать для уборки любых ресурсов, заявленных datagridviewmycustomcell, когда он больше не будет.

Примеры, которые я видел в Интернете, предложил использовать блок, чтобы обладать сроком службы объекта и иметь систему автоматически ее распоряжаться, но база не распознается при перемещении в корпус конструктора, поэтому я не могу написать Блок вокруг этого ... Что я не уверен, что я все равно хотел бы сделать, поскольку бы не проинструктируем время выполнения, чтобы освободить объект, который все еще можно использовать позже внутри базового класса?

Затем мой вопрос, код в порядке, как есть? Или, как его можно было бы повторно разрешить предупреждение? Я не хочу подавлять предупреждение, если только это действительно не подходит для этого.

Это было полезно?

Решение

Если вы используете Visual Studio 2010, то Ca2000 полностью сломан. Он также может быть разбит в других версиях FXCOP (AKA Code Analysis), но VS2010 - единственный, на которую я могу поручиться. Наша кодовая база предоставляет CA2000 Предупреждения для кода, как это ...

internal static class ConnectionManager 
{
    public static SqlConnection CreateConnection()
    {
         return new SqlConnection("our connection string");
    }
}

... Указание того, что соединение не расположено до того, как он не выйдет из объема в способе. Ну, да, это правда, но это не в пределах масштаба для приложения Как возвращается к абонеру - это весь точку метода! Точно так же, ваш аргумент конструктора не выходит из неисправности, но передается в базовый класс, поэтому он является ложным положительным от правила, а не фактической проблемы.

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

Другие советы

Там нет безопасного и элегантного способа иметь кроватный конструктор, пройдя новый IDisposable Объект к базовому конструктору, так как вы, как вы отмечаете, невозможно обернуть Chraced Constructor Call в любом виде try finally блокировать. Есть подход, который безопасен, но это вряд ли элегантно: определить метод утилиты что-то вроде:

internal static TV storeAndReturn<TR,TV>(ref TR dest, TV value) where TV:TR
{ 
  dest = value; return value;
}

У конструктора выглядят что-то вроде:

protected DataGridViewMyCustomColumn(ref IDisposable cleaner) : 
   base(storeAndReturn(ref cleaner, new DataGridViewMyCustomCell()))
{
}

Код, который нуждается в новом объекте, тогда должен позвонить в общедоступный статический заводский метод, который позвонил бы соответствующему конструктору в пределах try/finally блок, основная линия чья нуль cleaner как раз перед ним закончен, а чья чей finally блок позвонит Dispose на cleaner Если это не ноль. При условии, что каждый подкласс определяет аналогичный фабричный метод, этот подход гарантирует, что новый IDisposable Объект будет располагаться, даже если произошло исключение между временем, которое он создан, и время инкапсулирующего объекта подвергается воздействию клиентского кода. Уровень уродливой, но я не уверен, что ни приятнее другое шаблон гарантирует правильность.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top