C#中事件的最佳实践

1 c# events

在C#中,您可以在事件函数中使用返回值.但是,您只收到最后一个事件的返回值.此外,似乎没有办法获得前一个事件的返回值.

有什么好的做法?我应该经常使用void吗?根据我有限的经验,如果我想连锁价值必须使用ref

我怎么写一个活动?我想使用Func <ref t,returnT>,但ref在那里是非法的,我想动作是一样的.(我最终得到了以下内容).有没有办法在使用时使事件成为一行而不是两行ref

    delegate int FuncType(ref int a);
    static event FuncType evt;
    static void Main(string[] args)
    {
        evt += foo;
        var aa = 1;
        var a = evt(ref aa);
        evt += bar;
        var bb = 1;
        var b = evt(ref bb);
    }

    static int foo(ref int a)
    {
        a = a*3;
        return a;
    }

    static int bar(ref int a)
    {
        a=a +1;
        return a;
    }
Run Code Online (Sandbox Code Playgroud)

Inc*_*ito 8

如上所述,您可以使用GetInvocationList它来允许您单独调用每个方法并处理返回的数据.

但在此之前,请考虑使用EventHandler<T>EventArgs.

您可以拥有所需的" 一切 " EventArgs.检查以下示例代码:

public class BalanceChangedEventArgs : EventArgs
{
    public readonly double OldBalance;
    public readonly double NewBalance;

    public BalanceChangedEventArgs(double oldB, double newB)
    {
        OldBalance = oldB;
        NewBalance = newB;
    }
}

public class Account
{
    private double balance;

    public EventHandler<BalanceChangedEventArgs> balanceChanged;

    protected void OnBalanceChanged(BalanceChangedEventArgs eArgs)
    {
        if (balanceChanged != null)
            balanceChanged(this, eArgs);
    }

    public double Balance
    {
        get { return balance; }
        set
        {
            if (balance == value)
                return;

            OnBalanceChanged(new BalanceChangedEventArgs(balance, value));

            balance = value;
        }
    }
} 
Run Code Online (Sandbox Code Playgroud)


Ste*_*ary 7

不要将"事件"与"回调"混为一谈.如果您想为自定义提供"挂钩",请考虑以下其中一项:

  • 具有挂钩虚拟方法的基类.
  • 回调对象的接口,传递给构造函数或通过属性访问.
  • 委托传递给您的构造函数或通过属性访问.

如果您已经考虑了上述内容,并且仍然想要使用某个事件,那么您可以将"结果"包含在事件参数类型中,例如,e.Resulte.Handled.您仍然遇到多个事件处理程序可能会覆盖彼此的值的问题,因此您应该将该方法与其他答案所建议的迭代调用列表结合起来.要么整理所有结果,要么像早期退出策略那样使用e.Handled.