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

Удалить избыточный вызов конструктора делегата?

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

dispMap.OnDraw += new EventHandler(dispMap_OnDraw);

Для этой строки:

dispMap.OnDraw += dispMap_OnDraw;

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

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

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

4b9b3361

Ответ 1

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

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

Также приведена цитата из этой статьи MSDN:

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

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

Ответ 2

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

Ответ 3

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

Пример С#:

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
} 

Заключение: я не вижу причин менять код, они эквивалентны.

Ответ 4

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