Подтвердить что ты не робот

Почему пустой обработчик события делегирования вызывает предупреждение CA1061?

Обновление: Это происходит, когда параметр "Анализ кода" "Подавление результатов сгенерированного кода (только управляемый)" отключен, а в наборе правил установлено "Основные правила разработки Microsoft Basic".

В 2013-04-26 Microsoft подтвердила, что это ошибка, но не исправляет ее ни в этой, ни в следующей версии Visual Studio.

Ссылка на элемент MS Connect

Мы часто инициализируем обработчики событий пустым делегатом, чтобы избежать необходимости проверки нулей. Например:.

public EventHandler SomeEvent = delegate {};

Однако, начиная с компиляции некоторых из нашего кода в Visual Studio 2012 (окончательная первоначальная версия), я замечаю, что многие события в производных классах теперь запускаются CA1601: не скрывать методы базового класса в Visual Code 2012 Code Analysis.

Здесь образец, который вызовет предупреждение:

using System;
using System.ComponentModel;

[assembly: CLSCompliant( true )]

namespace TestLibrary1
{
    public abstract class Class1
    {
        public event PropertyChangedEventHandler PropertyChanged = delegate {};
    }

    public class Class2 : Class1
    {
        // this will cause a CA1061 warning
        public event EventHandler SelectionCancelled = delegate { };
    }

    public class Class3 : Class1
    {
        // this will not cause a CA1061 warning
        public event EventHandler SelectionCancelled;
    }
}

Примечание. В VS2012 предупреждение запускается при компиляции в .NET 4.5 или .NET 4.0. Тот же образец не вызывает предупреждение в VS2010.

Отклонения в производительности, Есть ли какие-либо законные причины, по которым мы не должны инициализировать события с пустыми делегатами? По умолчанию предполагается, что это, вероятно, просто причуда в анализе в Visual Studio 2012.

Здесь результат анализа кода для тех, у кого еще нет доступа к VS2012:

CA1061 Не скрывать методы базового класса. Измените или удалите "Class2.Class2()", потому что он скрывает более конкретный метод базового класса: "Class1.Class1()". TestLibrary1 Class1.cs 14

Добавление: Я обнаружил, что опция "Подавлять результаты сгенерированного кода" в анализе кода отключена.

Кроме того, я обнаружил, что это происходит, когда обработчик событий в базовом типе:

  • делегат, отличный от EventHandler или EventHandler, и
  • события как в базовом классе, так и в производном классе инициализируются с использованием анонимного метода или пустого делегата (либо встроенного, либо в конструкторе).

Возможная релевантность: мы запускаем RTM Visual Studio 2012, который был установлен на месте над кандидатом на выпуск.

4b9b3361

Ответ 1

Проблема заключается в том, что компилятор С# генерирует статический делегат, используемый для инициализации вашего делегата экземпляра, который называется одинаковым для Class1 и Class2.

Class1.CS$<>9__CachedAnonymousMethodDelegate1 существует для использования конструктором Class1 для инициализации PropertyCancelled, тогда как Class2.CS$<>9__CachedAnonymousMethodDelegate1_ существует для использования конструктором Class2 для инициализации SelectionCancelled.

Несчастливо, что компилятор С# не включает какую-то запись родительского класса "автоматически сгенерированный материал" при принятии решения о том, как назвать автоматически сгенерированный "материал" для дочернего класса. Взломайте это в ILDasm, и проблема сразу станет очевидной. Приятно знать, что вы нашли работу. Предупреждение вполне разумно игнорировать, учитывая, что вы не можете прикасаться к статическим делегатам из С#, благодаря неигровому именованию, отличному от С#.