CA1047 «Заставить члена вызывать частные, публичные или внутренние» и события C ++ / CLI - PullRequest
0 голосов
/ 02 декабря 2010

Когда я объявляю публичное событие в запечатанном классе C ++ / CLI, я получаю предупреждение анализа кода CA1047. Похоже, что предупреждение приходит от автоматически сгенерированных функций-членов. Как я могу исправить это предупреждение?

Вот пример. Этот код

ref class Test sealed {
public:
    event EventHandler^ blah;
};

генерирует:

предупреждение: CA1047: Microsoft.Design: Сделать член 'Test :: blah :: повышение (Object ^, EventArgs ^)' закрытым, открытым или внутренним

1 Ответ

1 голос
/ 02 декабря 2010

Я лучше задокументирую вопрос. Этот код

ref class Test sealed {
public:
    event EventHandler^ blah;
};

генерирует:

предупреждение: CA1047: Microsoft.Design: Сделать член 'Test :: blah :: Повышать (Object ^, EventArgs ^)' закрытым, открытым или внутренним

Да, если вы сами не указали методы доступа к событиям, компилятор сгенерирует их для вас. Он автоматически генерирует добавление, удаление и повышение доступа. Последний выглядит так, когда вы смотрите с ildasm.exe:

.method family hidebysig specialname instance void 
        raise_blah(object value0,
                   class [mscorlib]System.EventArgs value1) cil managed
{
    // etc..
}

Атрибут family - это то, что вызывает предупреждение анализа кода. Автоматически сгенерированные средства добавления и удаления, разумеется, общедоступны. Написание их самостоятельно - сомнительный обходной путь, вы действительно хотите сделать это, только если у вас есть реальная причина для реализации пользовательских средств доступа. Стандартная версия будет выглядеть так:

using namespace System::Runtime::CompilerServices;

ref class Test sealed {
private:
    EventHandler^ foo;
public:
    event EventHandler^ blah {
        [MethodImpl(MethodImplOptions::Synchronized)]
        void add(EventHandler^ d) { foo += d; }
        [MethodImpl(MethodImplOptions::Synchronized)]
        void remove(EventHandler^ d) { foo -= d; }
    private:
        void raise(Object^ sender, EventArgs^ e) { 
            EventHandler^ handler = foo;
            if (handler != nullptr) handler(sender, e);
        };
    }
};

Ну, это, безусловно, подавляет предупреждение. Я рекомендую вам использовать атрибут [SuppressMessage], если он не вращает ваш винт.

...