使用像处理一样工作的字段定义事件

本文关键字:工作 一样 字段 事件 定义 处理 | 更新日期: 2023-09-27 18:35:18

我的类我有一个事件,其中包含包含布尔字段 Prevent 的参数和一个默认函数,如果 Prevention == false,则执行一些操作。我希望我的类的用户能够通过在函数侦听事件中设置 Prevention = true 来阻止默认函数执行操作。但事实证明,首先调用默认函数,使用 Prevention = true,然后用户定义的函数更改字段的值。有没有办法改变函数调用的顺序?或者任何其他可以给我相同结果的方法?我通过定义用于检查默认函数是否应该执行其操作的 Func 字段来完成此操作,并且用户可以修改提供自己的函数的字段。它可以工作,但我不喜欢需要 2 个单独的函数,一个用于在事件触发时执行操作,另一个用于防止默认行为。

一些代码:

public Func<int, int, bool> PreventFunc = new Func<int,int,bool>( (x,y) => {return false;});
public struct MyEventArgs
{ 
     int x; 
     int y; 
     bool Prevent;
     public MyEventArgs (int i, int j, bool prev) { /*assignments*/ }
}
public delegate void MyEventDelegate(object sender, MyEventArgs e);
public event MyEventDelegate MyEvent = DefaultBehaviourFunction;
void DefaultBehaviourFunction (object sender, MyEventArgs e)
{
    if (e.Prevent == true) return;
    //do stuff
}

调用事件时

MyEvent.Invoke(sender, new MyEventArgs(i, j, PreventFunc(i,j)));

我希望它在没有 PreventFunc 的情况下工作,就像这样:

MyEvent += Func;
void Func (object sender, MyEventArgs e)
{ 
     if (e.x == 1) e.Prevent = true;
     //do stuff
}

使用像处理一样工作的字段定义事件

您可以通过从事件委托字段中获取调用列表、反转顺序并单独调用每个目标来实现您所要求的内容。但这将是对事件模式的滥用,而且只是笨拙。

相反,您应该像其他类一样实现这一点:让引发事件的方法成为检查Prevent值的方法,而不是其他处理程序。

例如:

private void OnMyEvent(int i, int j, bool prevent)
{
    MyEventDelegate handler = MyEvent;
    MyEventArgs e = new MyEventArgs(i, j, prevent);
    if (handler != null)
    {
        handler(this, e);
    }
    if (e.Prevent)
    {
        return;
    }
    // Member of same class, and we already know Prevent is false,
    // so just need to pass i and j.
    DefaultBehaviourFunction(i, j);
}

然后,不要直接使用 MyEvent.Invoke() 调用事件处理程序,而是调用 OnMyEvent() 方法。