gpt4 book ai didi

c# - 如何在 C# 中创建回调变量(真正的单播委托(delegate))

转载 作者:行者123 更新时间:2023-11-30 15:37:40 27 4
gpt4 key购买 nike

如何在 C# 中创建真正的单播委托(delegate)。即,委托(delegate)实例可以在其调用列表中引用一个(且仅一个)方法,因此可用作回调(对于单个订阅者)而不是事件(可能有多个订阅者)。

框架有类 System.Delegate 和 System.MulticastDelegate,这给人一种错误的印象,即 System.Delegate 是单播的,而 System.Multicast 委托(delegate)添加了多播功能。但是 System.Delegate 的 MSDN 文档 http://msdn.microsoft.com/en-us/library/system.delegate.aspx表明 System.Delegate 实际上是多播的...

“委托(delegate)的调用列表是一组有序的委托(delegate),其中列表的每个元素都恰好调用委托(delegate)所表示的方法之一。”

...而 System.MulticastDelegate 的文档并没有真正解释它提供的额外行为。

这方面的官方文档相当困惑,但有一点很明确,即最终用户不能从 System.Delegate 或 System.MulticastDelegate 派生。那么,框架是否支持任何方式来创建真正的单播委托(delegate),该委托(delegate)可用作变量来存储对单个回调的引用?

@dtb。如果我可以使用单播委托(delegate),那么就不需要进行运行时检查。当然,应用程序逻辑仍然可能以其他方式失败,例如分配了错误的处理程序,但至少如果我使用单播委托(delegate),那么存在多个处理程序的问题我只期望一个是一个简单的问题不存在,因此要检查的东西少了,单元测试更简单,设计更优雅。此外,如果具有返回值的方法的委托(delegate)在其调用列表中有多个处理程序,则返回给调用者的是列表中最后一个处理程序返回的值,而不是第一个。

最佳答案

如果您真的需要一个带有事件的“单播”委托(delegate),为什么不简单地为该事件实现您自己的添加/删除方法呢?

Delegate 的“问题”是 MulticastDelegate 是派生类,因此如果有人将 MulticastDelegate 对象分配给 Delegate 变量,那么您将始终拥有一个 MulticastDelegate

例如,我们可以将默认的 event 实现简化为:

private ChangedEventHandler _changed;
public event ChangedEventHandler Changed
{
add
{
_changed += value;
}
remove
{
_changed -= value;
}
}

现在让我们将事件实现更改为:

private ChangedEventHandler _changed;
public event ChangedEventHandler Changed
{
add
{
_changed = value; // Do NOT combine delegates
}
remove
{
_changed -= value;
}
}

现在您拥有的(几乎)是一个单播委托(delegate),因为事件语法用户不能直接分配一个多播委托(delegate)并且只存储最后分配的委托(delegate)。如果您的用户真的是恶意的,他们可以创建一个 MulticastDelegate,然后将该委托(delegate)添加到您的事件处理程序中。如果您确实需要防止这种情况,您可以将此检查添加到 add 方法中:

if (value.GetInvocationList().Length > 1)
throw new ArgumentException("MulticastDelegates are not allowed here.");

关于c# - 如何在 C# 中创建回调变量(真正的单播委托(delegate)),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12300540/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com