Удалить избыточный вызов конструктора делегата?
Я загрузил ReSharper и сказал мне изменить эту строку:
dispMap.OnDraw += new EventHandler(dispMap_OnDraw);
Для этой строки:
dispMap.OnDraw += dispMap_OnDraw;
Поскольку первая строка является "избыточным вызовом конструктора делегата".
Это правда? В автоматически создаваемом коде разработчика для форм синтаксис основан на первом фрагменте кода и при вводе текста dispMap.OnDraw +=
и нажатии TAB среда IDE автоматически генерирует new EventHandler(dispMap_OnDraw)
Мне просто интересно об этом. У ReSharper есть точка?
Ответы
Ответ 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, и он говорит мне то же самое!