2016-09-21 66 views
3

我做这样的事情的处理程序添加到的PropertyChanged与事件处理程序的属性类型:为什么我不能(参照法)

void komar_EventHandler(object sender, EventArgs e) 
{ 
    // Do somethig 
} 

... 
{ 
    Komar k = new Komar(); 

    k.PropertyChanged += komar_EventHandler; // OK (why?) 


    EventHandler methodRef = komar_EventHandler; 

    k.PropertyChanged += methodRef;        // Error ! 
    k.PropertyChanged += (PropertyChangedEventHandler)methodRef; // Error ! 


    // I know solution, but I don't like it :) 
    k.PropertyChanged += (s, e) => { methodRef(s, e); }; 

} 

为什么我可以马上添加不同类型的处理程序,但我不能使用引用方法?

+1

阅读[这](https://开头msdn.microsoft.com/en-us/library/mt654057.aspx)。 – Maarten

+0

什么是错误,你的研究显示了什么? http://stackoverflow.com/questions/28522523/cannot-implicitly-convert-type-system-eventhandler-to-system-eventhandlerobject – CodeCaster

回答

2
k.PropertyChanged += komar_EventHandler; // OK (why?) 

由于编译器的方法组komar_EventHandler自动转换为PropertyChangedEventHandler委托。这是一样的,如果你的代码是:

k.PropertyChanged += new PropertyChangedEventHandler(komar_EventHandler); 
k.PropertyChanged += methodRef;        // Error ! 

PropertyChanged事件需要一个PropertyChangedEventHandler,不是EventHandler。不同委托类型之间没有隐式转换。

k.PropertyChanged += (PropertyChangedEventHandler)methodRef; // Error ! 

EventHandler不能转换到一PropertyChangedEventHandler;它只是不是一个有效的转换。你可以,但是,创建一个PropertyChangedEventHandlerEventHandler

k.PropertyChanged += new PropertyChangedEventHandler(methodRef); 
+0

不错的答案,但我会评论OP不喜欢的解决方案(与拉姆达) – Fabjan

0

Thomas Levesque你说得挺有道理的。我忘了这个:

k.PropertyChanged += komar_EventHandler; // OK (why?) 
// because: 
k.PropertyChanged += new PropertyChangedEventHandler(komar_EventHandler); 

但是,我的问题的解决方案是,但其他。

编译器需要一种方法,因此该解决方案是:

k.PropertyChanged += methodRef.Invoke;        // OK ! 
k.PropertyChanged += (PropertyChangedEventHandler)methodRef.Invoke; // OK ! 

编辑:
我们可以做到这一点也这样说:

k.PropertyChanged += new PropertyChangedEventHandler(methodRef); 
// Debugger showed me that k.PropertyChanged has reference 
// to the method methodRef.Invoke same as k.PropertyChanged += methodRef.Invoke; 
+0

是的,'methodRef.Invoke'也可以工作,因为它是一个兼容签名的方法 –

+0

@ThomasLevesque哦,我刚刚看到你写完我的答案之前已经完成了答案。所以...你应该赢得:) – marbel82