Удалить избыточный вызов конструктора делегата? - PullRequest
12 голосов
/ 16 августа 2011

Я скачал ReSharper, и он говорит мне изменить эту строку:

dispMap.OnDraw += new EventHandler(dispMap_OnDraw);

Чтобы быть этой строкой:

dispMap.OnDraw += dispMap_OnDraw;

Поскольку первая строка является "избыточным вызовом конструктора делегата". "

Это правда?В автоматически сгенерированном коде конструктора для форм синтаксис основан на первом фрагменте кода, и при вводе dispMap.OnDraw += и нажатии клавиши TAB среда IDE автоматически генерирует new EventHandler(dispMap_OnDraw)

Мне просто интересно это.У ReSharper есть точка?

Ответы [ 4 ]

10 голосов
/ 16 августа 2011

Да, это правильно.Я сделал это в нескольких случаях.

Вызов конструктора делегата должен быть неявным;тип может быть выведен из OnDraw и проверен по сигнатуре метода dispMap_OnDraw.

Кроме того, цитата из этой статьи MSDN выглядит актуальной:

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

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

5 голосов
/ 16 августа 2011

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

3 голосов
/ 16 августа 2011

Если вы сравните сгенерированный IL в обоих случаях, вы увидите, что они одинаковы.Вот оба случая в C # и IL, к которым они приводят.

Пример C #:

namespace EventTest
{
    public class Publisher
    {
        public delegate void SomeEvent(object sender);
        public event SomeEvent OnSomeEvent;
        public event SomeEvent OnOtherEvent;
    }

    public class Subscriber
    {
        public Subscriber(Publisher p)
        {
            p.OnSomeEvent += new Publisher.SomeEvent(Respond);
            p.OnOtherEvent += Respond;
        }

        public void Respond(object sender)
        {

        }
    }
}

Вот IL для конструктора.Обратите внимание на строки от IL_000a до IL_0028.

.method public hidebysig specialname rtspecialname 
        instance void  .ctor(class EventTest.Publisher p) cil managed
{
  // Code size       48 (0x30)
  .maxstack  8
  IL_0000:  ldarg.0
  IL_0001:  call       instance void [mscorlib]System.Object::.ctor()
  IL_0006:  nop
  IL_0007:  nop
  IL_0008:  ldarg.1
  IL_0009:  ldarg.0
  IL_000a:  ldftn      instance void EventTest.Subscriber::Respond(object)
  IL_0010:  newobj     instance void EventTest.Publisher/SomeEvent::.ctor(object,
                                                                          native int)
  IL_0015:  callvirt   instance void EventTest.Publisher::add_OnSomeEvent(class EventTest.Publisher/SomeEvent)
  IL_001a:  nop
  IL_001b:  ldarg.1
  IL_001c:  ldarg.0
  IL_001d:  ldftn      instance void EventTest.Subscriber::Respond(object)
  IL_0023:  newobj     instance void EventTest.Publisher/SomeEvent::.ctor(object,
                                                                          native int)
  IL_0028:  callvirt   instance void EventTest.Publisher::add_OnOtherEvent(class EventTest.Publisher/SomeEvent)
  IL_002d:  nop
  IL_002e:  nop
  IL_002f:  ret
} 

Вывод: я не вижу смысла менять ваш код, они эквивалентны.

0 голосов
/ 16 августа 2011

отлично работает, у меня DevExpress и мне тоже самое говорят!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...