2017-01-16 5 views
0

В чем разница между - = new EventHandler (Method) to - = Метод , когда метод передается как параметр?- = new EventHandler (Method) vs - = Метод при передаче метода как параметр

Почему removeNew не удалось отказаться от подписки?

см следующий класс:

public class Class1 
{ 
    public EventHandler _eh; 

    public void OnEvent() 
    { 
     if (_eh != null) 
     { 
      _eh.Invoke("", new EventArgs()); 
     } 
    } 

    public void remove(EventHandler evHandler) 
    { 
     // unsubscribe successfully 
     _eh -= evHandler; 
    } 

    public void removeNew(EventHandler evHandler) 
    { 
     // failed to unsubscribe 
     _eh -= new EventHandler(evHandler); 
    } 
} 

Update:

@SchabseLaks, просто clearify мой questation я добавляю код, который называют это методы:

public partial class Form1 : Form 
{ 
    Class1 c1 = new Class1(); 
    public Form1() 
    { 
     InitializeComponent(); 
     c1._eh += Hello; 
    } 

    private void button1_Click(object sender, EventArgs e) 
    { 
     c1.OnEvent(); 
    } 

    private void Hello(object sender, EventArgs e) 
    { 
     MessageBox.Show("hello"); 
    } 

    private void button2_Click(object sender, EventArgs e) 
    { 
     c1.removeNew(Hello); 
    } 

    private void button3_Click(object sender, EventArgs e) 
    { 
     c1.remove(Hello); 
    } 
} 
+6

Яблоко, указывающее на яблоко, - это не то же яблоко, на которое указывает яблоко. – CodeCaster

ответ

7

Делегат может быть создан только из метода.

new EventHandler(evHandler) является сокращением на new EventHandler(evHandler.Invoke), так как Invoke - это метод любого типа делегата, который фактически вызывает делегата.

Поскольку ваш _eh не имеет evHandler.Invoke в качестве обработчика, это ничего не делает.

+0

Справа. Стоит добавить, почему это принято вообще, а не просто ошибка компилятора: если типы делегатов различны, это полезный способ получить делегат другого типа, который имеет такой же эффект (например, «новое действие <объект, EventArgs> (evHandler) '). В компиляторе нет особого исключения, что делает его ошибкой, если типы одинаковы, поэтому они приняты. – hvd

0

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

So;

var x = new EventHandler(myDelegate); 
var y = new EventHandler(myDelegate); 
Assert.IsTrue(x == y); 


var x = new EventHandler(myDelegate); 
var y = new EventHandler(anotherDelegate); 
Assert.IsFalse(x == y); 

При + = или - = новый экземпляр EventHandler, таких как

myHandler -= new EventHandler(someDelegate); 

new EventHander передается в метод декремента экземпляра myHandler, где его целевой делегат по сравнению с тем, что уже список. Его цель, которая удаляется, а не новый экземпляр EventHandler. И наоборот, когда вы;

myHandler += new EventHandler(someDelegate); 

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