是否可以发送'sender'的引用而不将其明确指定为基于委托的事件处理中的参数?
我有一个内部类,它引发了一些事件,我想明确地调用事件用于测试目的。
public class Manager {
public class DataStruct {
public int Id { get; private set; }
public event EventHandler Event1; // Can't be called by other classes
public void fireEvent1(Event1();} // So another caller...
// Delegates *can* be called by other classes
public delegate void DelegateHandler(DataStruct sender);
public DelegateHandler NewEvent;
public void DelegateHandler(DataStruct sender) {
MessageBox.Show(string.Format(
"{0} raises event", sender.Id));
}
}
}
// Form1 ///////////////////////////////////////////////////////////////////
partial class Form1 {
Manager.DataStruct dsRaiser, dsListener;
private void Form1_Load(object sender, EventArgs e) {
dsRaiser.Event1 += dsListener.SOME_HANDLER;
dsRaiser.NewEvent += dsListener.DelegateHandler;
}
private void button1_Click(object sender, ...) {
dsRaiser.fireEvent1(); // No argument needed but fireEvent1, not Event1().
}
private void button2_Click(object sender, ...) {
dsRaiser.NewEvent(dsRaiser); // Way to omit parameter dsRaiser?
}
//////////////////////////////////////////////////////////////////////////
答案 0 :(得分:1)
如果您的处理程序方法需要使用发件人的引用,那么您必须传递该引用。
如果没有,只需声明一个无参数无效的委托,如Action
。
但是在考虑事件时,该参数应该由引发事件本身的类传递。 (记住事件不是要从外面调用的。)
因此,如果您真的想使用简单的委托而不是事件,则必须传递参数。
如果您需要发件人,则需要完全按照您对事件所做的操作:创建一个方法来“提升”委托,并在该方法中将this
作为发件人传递。
但考虑到你必须在两种情况下做同样的事情,我肯定会使用这个事件。
public class DataStruct {
public int Id { get; private set; }
public event EventHandler Event1; // Can't be called by other classes
// you need to pass those parameters to the event when called.
public void fireEvent1{Event1(this, new EventArgs());}
// Delegates *can* be called by other classes, but only with all parameters passed.
public delegate void DelegateHandler(DataStruct sender);
public DelegateHandler NewEvent;
// To avoid passing parameters, you need to do exactly what you did with the event
public void RaiseDelegate() { NewEvent(this); }
public void DelegateHandler(DataStruct sender) {
MessageBox.Show(string.Format(
"{0} raises event", sender.Id));
}
}