通过EventHandler传回返回值

Ler*_*ins 33 c# return-value event-handling

我试图写入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<Record>>(table_WhenData);
            table.WhenDead += new EventHandler<EventArgs>(table_WhenDead);
            table.Start();
        }

    public void table_WhenData(object sender, DataEventArgs<Record> e)
    {
        return true;
    }
Run Code Online (Sandbox Code Playgroud)

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

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

任何建议都非常感谢.

Jos*_*rke 49

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

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

public class 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;
}
Run Code Online (Sandbox Code Playgroud)

编辑

我喜欢Jon Skeet的措辞:做出EventArgs可变的.也就是说,事件的消费者可以修改EventArgs对象的状态,从而允许事件的提升者获得该数据.

  • 如果有多个事件处理程序(对于上面给出的代码示例,有些将其设置为 true,其他则将此对象值设置为 false),事件订阅者代码如何确定?就像最后一个设置获胜的订阅者一样 (2认同)
  • @bashahul - 是的,调用者看到的是所有处理程序所做的操作的累积,因此如果多个处理程序设置一个值,它将是最后一个。如果您期望多个处理程序,那么您需要确定设计意图是什么,并让所有处理程序遵循该意图。例如,在 Josh 提到的“取消”模式中,一旦一个处理程序设置“取消”,其他处理程序就可以对此进行测试,但不执行任何操作。在其他一些情况下,您可能让每个处理程序将一个项目附加到响应列表中,以便调用者可以看到所有这些项目。 (2认同)

AFi*_*ein 26

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

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

// 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);
    }
Run Code Online (Sandbox Code Playgroud)

在订户中:

// 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";
}
Run Code Online (Sandbox Code Playgroud)

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

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

  • 如果您使用自定义委托方法,如果您有多个事件处理程序返回不同的值会发生什么?事件提升者收到哪个返回值? (3认同)
  • 获取每个返回值的方法如何:http://stackoverflow.com/a/1237017/1999165 (3认同)

Jon*_*eet 19

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

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

  • 我的头疼,试图理解一种方式,请使EventArgs可变! (3认同)