在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;
}
答案 0 :(得分: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;
}
}
}
答案 1 :(得分:7)
不要将“event”与“callback”混淆。如果您想为自定义提供“挂钩”,请考虑以下其中一项:
如果您已考虑上述内容,但仍想使用某个事件,则可以将“结果”作为事件参数类型的一部分,例如e.Result
或e.Handled
。您仍然遇到多个事件处理程序可能会覆盖彼此的值的问题,因此您应该将该方法与其他答案所建议的迭代调用列表结合起来。要么整理所有结果,要么像e.Handled
那样使用“提前退出”策略。
答案 2 :(得分:3)
您可能需要查看Microsoft的Event Design文档。
答案 3 :(得分:2)
如果您想在事件有多个订阅者时获取返回值,请使用Delegate.GetInvocationList
。然后你可以说
foreach(FuncType d in evt.GetInvocationList()) {
int value = d(parameter);
// do something with value
}
但是,通常,最好避免在事件处理程序中返回值。
答案 4 :(得分:2)
“最佳做法”是仅使用void
事件处理程序。正是因为最后一个价值问题。
如果需要组合结果,请定义具有适当属性的EventArgs后代。使用列表或总和值等。