创建自定义事件 - 对象发送者还是类型发送者?

2024-03-07

我搜索了档案,发现了很多关于发件人是什么以及为什么应该使用该模式的问题,但我没有看到任何有关自定义事件和type如果发件人。

假设我正在创建一个名为 Subscription 的自定义类,它实现了 ISubscription,并且我有一些名为 SubscriptionEventArgs 的事件参数。如果订阅有一个名为 Changed 的​​事件,那么事件签名 Changed(ISubscription sender, SubscriptionEventArgs e) 有什么问题吗?

一些代码可以帮助解决这个问题:

public class SubscriptionEventArgs : EventArgs
{
    // guts of event args go here
}

public interface ISubscription
{
    event Action<ISubscription, SubscriptionEventArgs> Changed;
}

public class Subscription : ISubscription
{
    public event Action<ISubscription, SubscriptionEventArgs> Changed;

    private void OnChanged(SubscriptionEventArgs e)
    {
        if (Changed!= null)
        {
            Changed(this, e);
        }
    }
}

如果您只是鄙视使用操作来代替“EventHandler”,那么您可以做同样的事情,但使用自定义通用“EventHandler”。

public delegate void EventHandler<TSender, TEventArgs>(TSender sender, TEventArgs e);

public class SubscriptionEventArgs : EventArgs
{
    // guts of event args go here
}

public interface ISubscription
{
    event EventHandler<ISubscription, SubscriptionEventArgs> Changed;
}

public class Subscription : ISubscription
{
    public event EventHandler<ISubscription, SubscriptionEventArgs> Changed;

    private void OnChanged(SubscriptionEventArgs e)
    {
        if (Changed!= null)
        {
            Changed(this, e);
        }
    }
}

响应汉斯对示例事件处理程序的请求:

public class SubscriptionCollection
{
    // what is actually holding the subscriptions is not really relevant to the question
    private List<ISubscription> _subscriptions;

    public SubscriptionCollection()
    {
        _subscriptions = new List<ISubscription>();
    }

    public void Add(ISubscription subscription)
    {
        subscription.Changed += new EventHandler<ISubscription, SubscriptionEventArgs>(Subscription_Changed);
        _subscriptions.Add(subscription);
    }

    private void Subscription_Changed(ISubscription sender, SubscriptionEventArgs e)
    {
        // Now when the subscription changed event is being handled by the collection
        // I don't have to look up the subscription in the list by some key and I don't 
        // have to cast sender to the correct type because the event handler was typed
        // correctly from the beginning.
    }
}

在列表中查找订阅可能看起来微不足道,但如果我正在处理非常大的数据集,并且新的数据量通过实时流传入应用程序,该怎么办?必须停下来从列表中获取参考或完成铸造步骤的成本是没有意义的。他们在 2.0 中为我们提供了泛型来解决这个问题,所以我不明白为什么我们没有得到通用事件处理程序,这让我质疑通用事件处理程序有什么问题?


我实际上很困惑为什么在设计.Net Framework v2时,MS没有提供EventHandler正如你所描述的那样 - 与TSender and TEventArgs作为两个通用参数。 (在 v1 和 v1.1 中,由于它们没有泛型,我完全理解为什么他们没有创建数千个额外的委托类型来处理所有可能的事件。)如果我没记错的话,您仍然可以使用通用处理程序收听更具体的事件:

public event EventHandler<Button, MouseDownEventArgs> MouseDown;

private void ObservingMethod(object sender, EventArgs e) { }

MouseDown += new EventHandler<Button, MouseDownEventArgs>(ObservingMethod);

由于您没有将观察者暴露给可观察的对象,因此我不认为这会成为问题;您只是在到达事件处理程序后不需要进行类型检查“以防万一”。我认为这将是一个很棒的实践,尽管有点不标准,因为微软决定不包括它。

正如我在上面的评论中所指出的,我更愿意看到以下 EventHandler 的定义,以便您确实可以始终使用非常通用的处理程序方法,作为我的代码示例:

public delegate void EventHandler<TSender, TEventArgs>(TSender sender, TEventArgs e)
    where TEventArgs : EventArgs;
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

创建自定义事件 - 对象发送者还是类型发送者? 的相关文章

  • 正则表达式的命名空间不起作用

    我正在翻新一些曾经在 NET Framework 3 5 上运行的旧代码 使其能够使用 C 在 NET Framework 4 上运行 以下正则表达式过去在 3 5 版本中运行良好 但由于某些奇怪的原因不再运行 public static
  • 使用 jquery 事件 keydown 模拟在文本区域上输入不起作用

    我正在尝试制作 Facebook 自动回复消息脚本 这是我的代码 window load function var a setInterval function var e titlebarText html if e else texta
  • 如果将摘要添加为参考,则摘要不会显示在程序集中

    我用 C 创建了一个 类库 其中包含许多带有摘要的函数 XML 文档注释 例如
  • 有没有基于 WPF 的 Markdown 渲染器? [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我们有基于 WPF 的应用程序 我们有单独的字符串存储库 其中的文本在网络中进行编辑 在我们的 WPF
  • 为什么在 C# 中使用 String.Concat()?

    我想知道这个问题有一段时间了 为什么使用String Concat 而不是使用 操作员 我明白了String Format因为它是一个空洞使用 运算符并使您的代码看起来更好 例如 string one bob string two jim
  • ASP.NET Core Identity 更改登录 URL

    我正在使用 ASP NET Core 2 1 并且使用脚手架来添加身份 工作正常 除了当我尝试转到需要登录的页面时 它需要我 Identity Account Login ReturnUrl 如何将其更改为仅转到 Account Login
  • 在 Web 浏览器中禁用 F5 [重复]

    这个问题在这里已经有答案了 可能的重复 禁用浏览器的后退按钮 https stackoverflow com questions 961188 disable browsers back button 如何禁用浏览器上的 F5 刷新 htt
  • 如何在 Windows CE 中使用 VB.Net 访问条码扫描仪

    最近我被要求开发一个应用程序摩托罗拉 MK4000 http www motorola com Business US EN Business Product and Services Micro Kiosks Micro Kiosks M
  • .pdbs 会减慢发布应用程序的速度吗?

    如果 dll 中包含 pdb 程序调试 文件 则行号将出现在引发的任何异常的堆栈跟踪中 这会影响应用程序的性能吗 这个问题与发布与调试 即优化 无关 这是关于拥有 pdb 文件的性能影响 每次抛出异常时都会读取 pdb 文件吗 加载程序集时
  • MSMQ接收和删除

    是否有任何选项可以在读取消息后将其从 MSMQ 中删除 比如 接收 删除可以作为原子操作运行吗 听起来您想查看下一条消息 然后在处理完成后接收它 Message message Queue Peek Queue ReceiveById me
  • Nhibernate:连接表并从其他表获取单列

    我有以下表格 create table Users Id uniqueidentifier primary key InfoId uniqueidentifier not null unique Password nvarchar 255
  • Java中单例的其他方式[重复]

    这个问题在这里已经有答案了 只是我在考虑编写单例类的其他方法 那么这个类是否被认为是单例类呢 public class MyClass static Myclass myclass static myclass new MyClass pr
  • 如何在向 MSMQ 发送消息时启用负源日志?

    我试图通过 System Messaging MessageQueue NET 发送消息 但消息不断消失 我见过有人建议启用负源日志 但似乎不知道这是如何完成的 任何人 Message m new Message m UseDeadLett
  • project.json 等效于 InternalsVisibleTo

    Net Core 的项目 json https learn microsoft com en us dotnet articles core tools project json copyright允许配置传统 Net 应用程序使用通常放置
  • 为什么 EF 5.0 在编译为 sql 时不支持此 EF 4.x LINQ 语法?

    我有一些代码最近从 EF 4 2 升级到 EF 5 0 实际上是 EF 4 4 因为我在 Net 4 0 上运行 我发现我必须更改查询的语法 我很好奇为什么 让我从问题开始 我有一个由客户端定期填充的事件日志表 对于每个事件日志 都会在报告
  • MVC2 中隐藏字段的替代方案

    我有一个 viewModel 其中包含一个在传递给部分视图之前填充的字符串 我需要能够在发布表单时取回数据 目前我已经创建了一个隐藏字段并将数据绑定到它 然后 当回发时 我可以从表单集合中获取数据 这并不完全是我想要的 我希望数据完全隐藏在
  • 无法启动 Windows 服务,错误 1064

    我编写了一个在 Win10 上运行的 Windows 服务 它运行得非常好 直到我决定对其进行一些更改 我重写了一些逻辑 在调试和发布配置中进行了测试 一切都很好 然后 我使用卸载了当前版本的服务installutil exe u serv
  • C# 数据表来保存表格(无限嵌套)

    我相对较新C 但来自C C 背景 我需要一个类似于的数据类型 类 DataTable 但允许存储的列保存 简单 类型 int float boolean string 以及相同类型的数据 以便一个列可以保存另一个表 该表也具有存储表等的列
  • TextBox 焦点的 WinForms 事件?

    我想添加一个偶数TextBox当它有焦点时 我知道我可以用一个简单的方法来做到这一点textbox1 Focus并检查布尔值 但我不想那样做 我想这样做 this tGID Focus new System EventHandler thi
  • 为什么密码错误会导致“填充无效且无法删除”?

    我需要一些简单的字符串加密 所以我编写了以下代码 有很多 灵感 来自here http www codeproject com KB security DotNetCrypto aspx create and initialize a cr

随机推荐