Да, это будет работать так, как вы хотите.
Сравнение не по ссылке, а по значению, что означает, что вы можете отменить подписку для другого делегата, если он указывает на один и тот же метод в том же объекте.
Другими словами, это будет прекрасно работать:
var delegate1 = new ExternalObjectClickEventHandler(MethodA);
var delegate2 = new ExternalObjectClickEventHandler(MethodA);
ExternalObject.Click += delegate1;
ExternalObject.Click -= delegate2;
Анонимные методы отличаются, но вы не можете сделать это:
public MethodB()
{
ExternalObject.Click += () => { return 10; };
}
public MethodC()
{
ExternalObject.Click -= () => { return 10; };
}
Хотя методы содержат один и тот же код, они считаются разными, и поэтому это не будет работать, то есть MethodC
не отменит подписку, добавленную вами в MethodB
.
Чтобы решить эту проблему, вы должны хранить делегат между вызовами, например:
private ExternalObjectClickEventHandler _ClickEventHandler;
public MethodB()
{
_ClickEventHandler = () => { return 10; };
ExternalObject.Click += _ClickEventHandler;
}
public MethodC()
{
ExternalObject.Click -= _ClickEventHandler;
}
Но код, который вы показали, будет работать.
Что касается вашего вопроса, что происходит за кулисами, так это то, что следующие две строки кода идентичны, когда речь идет о сгенерированном коде:
ExternalObject.Click += MethodA;
ExternalObject.Click += new ExternalObjectClickEventHandler(MethodA);
Второй код - это то, что генерируется из первого (при условии, что тип события соответствует показанному.)
Первый синтаксис (в какой-то момент) был добавлен как «синтаксический сахар», который переводится компилятором, как будто вы написали второй синтаксис. Обратите внимание, что это происходит только в том случае, если скомпилированный может определить правильный тип 100%. Я видел несколько случаев (которые сейчас не помню), когда вам приходилось использовать полный синтаксис, потому что компилятор не мог понять, что вы имели в виду. В частности, перегрузки методов и обобщенные значения могут запутать это в этом отношении.