通过EventHandler传回返回值

我试图写入API,我需要在从表中获取数据时调用eventhandler。 像这样的东西:

public override bool Run(Company.API api) { SomeInfo _someInfo = new SomeInfo(); if (_someInfo.Results == 1) return true; else return false; using (MyTable table = new MyTable(api)) { table.WhenData += new EventHandler<DataEventArgs>(table_WhenData); table.WhenDead += new EventHandler(table_WhenDead); table.Start(); } public void table_WhenData(object sender, DataEventArgs e) { return true; } 

我遇到的问题是我不知道如何将返回值从table_WhenData传递回Run方法。

我尝试了很多方法(比如尝试将_someInfo传递给方法),但我似乎无法正确使用语法。

任何建议都非常感谢。

这里的常见模式不是从事件处理程序返回任何数据,而是向事件参数对象添加属性,以便事件的使用者可以设置调用者随后可以访问的属性。 这在UI处理代码中非常常见; 你会看到所有地方的取消事件概念。

以下是伪代码,而不是编译就绪。 其目的是展示模式。

 public MyEventArgs : EventArgs { public bool Cancel{get;set;} } public bool fireEvent() { MyEventArgs e=new MyEventArgs(); //Don't forget a null check, assume this is an event FireEventHandler(this,e); return e.Cancel; } public HandleFireEvent(object sender, MyEventArgs e) { e.Cancel=true; } 

编辑

我喜欢Jon Skeet的措辞:让EventArgs变得可变。 也就是说,事件的使用者可以修改EventArgs对象的状态,从而允许事件的提升者获取该数据。

我知道这是一个老post,但万一有人碰到它,肯定有可能做到这一点。 您声明自己的委托,它返回一个值,然后将该事件基于此新委托。 这是一个例子:

在事件声明者/出版商中:

 // the delegate public delegate string ReturnStringEventHandler(object sender, EventArgs args); // the event public event ReturnStringEventHandler StringReturnEvent; // raise the event protected void OnStringReturnEvent(EventArgs e) { if (StringReturnEvent != null) // make sure at least one subscriber // note the event is returning a string string myString = StringReturnEvent(this, e); } 

在订户中:

 // Subscribe to event, probably in class constructor / initializer method StringReturnEvent += HandleStringReturnEvent; // Handle event, return data private string HandleStringReturnEvent(object sender, EventArgs e) { return "a string to return"; } 

.NET在AssemblyResolve事件中提供了一个示例,它使用ResolveEventHandler委托来返回数据,在本例中是对所需程序集的引用。 有关AssemblyResolve事件的MSDN文章

我亲自使用AssemblyResolve事件和自定义委托技术从事件中返回数据,它们都在Visual Studio 2010上按预期工作。

你可以做到的唯一方法是使其中一个参数(最好是“args”而不是发送者)可变。 如果它还不是可变的,那你基本上就遇到了问题 – 没有办法把信息拿出来。

(好吧,有一种方法 – 你可以保持事件参数本身不可变,但是让它的一个成员成为一个方法,它最终会调用由代码注册的委托,从而首先引发事件。但这太可怕……)

一个简单的解决方案是使用一个闭包:

 public override bool Run() { SomeInfo someInfo = ... table.WhenData += (obj, args) => { someInfo.Return = something }; }