【问题标题】:Why is generic EventHandler<TArgs> so under-used?为什么泛型 EventHandler<TArgs> 未被充分利用?
【发布时间】:2010-11-12 06:50:07
【问题描述】:

.NET 2.0 增加了EventHandler&lt;TArgs&gt; 泛型委托类型以简化编写自定义事件的过程;不必定义EventArgs 类及其对应的委托(例如MyEventArgsMyEventHandler),您只需编写args 类。

考虑到这一点,为什么这种委托类型在 .NET Framework 中几乎没有出现?我知道大多数核心 API 是在引入泛型之前开发的,但即使在 WPF 等框架的新部分中,它们也选择显式定义委托类型;例如RoutedEventHandler 而不是 EventHandler&lt;RoutedEventArgs&gt;

通用事件处理程序委托是否存在固有问题?我经常使用它,但我担心我的代码与内置类相比显得非常不合适。

【问题讨论】:

  • 我怀疑引入EventHandler&lt;T&gt; 只是时机不对。到它被引入时,另一种模式(明确命名的委托)已经牢固确立,开始转向通用委托类型可能会被视为造成更大的混乱(导致困惑的程序员问,“什么那个代表又被叫到了吗?FooEventHandlerEventHandler&lt;Foo&gt;?") -- 这让我很好奇转向IEvent&lt;T&gt;(由 F# 和 Rx 框架引入)是否会奏效。
  • WPF 于 2003 年 7 月开始,远在泛型可用之前。当然,Windows 窗体也是如此。

标签: c# events generics delegates


【解决方案1】:

只是历史的偶然。如果我们在 .NET 1 中有泛型,大多数其他委托将不存在。

【讨论】:

    【解决方案2】:

    我不认为这有什么问题。它框架的某些地方使用...在GeoCoordinateWatcher.Position事件中,只是作为一个随机示例。

    在代码中看到比RoutedEventHandler 之类的特定类型名称有点笨拙 - 因为您将在 WPF/Silverlight 中使用 RoutedEventHandler 一个 很多,也许这就是为什么 MS决定给它自己的类型。

    【讨论】:

      【解决方案3】:

      也可能是当您编写框架级代码时,您往往会更加明确。当您编写工具包和应用程序级代码时并非如此。

      【讨论】:

        【解决方案4】:

        以下只是我个人的意见,但对我来说似乎(显然)是合理的; 如果我们仔细看看您是如何使用 .net 和 v studio 工作的,就会发现泛型类型符号似乎泄露了一些“美”。

        List<string> lst = new List<string>();
        lst.Add("hello world");
        

        虽然上面的代码非常简单、直接并且得到 Intelli sense 的良好支持,但 EventHandler 的“外观和感觉”看起来并不那么清晰。默认的 Intelli 支持将仅建议 EventHandler,而不是其泛型。此外,符号看起来很糟糕:

        private event EventHandler<MyClass> SomeEvent;
        private event EventHandler<AnotehrClass> OtherEvent;
        privete event EventHandler<MoreClass> MoreEvents;
        



        在浏览代码时,您每次都会阅读“EventHandler”,并且您可能会联想到这些委托,因为您习惯于通过名称来识别类型之间的关系。

        另一方面,也可能有一个不太等位和更多技术/逻辑的解释:
        首先,您总是在处理方法中获得一个发送者对象。虽然乍一看这似乎很有用 - 它是曾经使用过的大麦。
        此外,您的论点必须源自 EventArgs,由于使用了现有组件,这可能很烦人,有时甚至是不可能的。
        除了典型的泛型(例如 IList/List)之外,您还漏掉了使用更抽象类型(如接口)或仅使用简单类型(如 double)的可能性。
        最后但并非最不重要的是,微软引入了那些符号规则/建议 - 对于您关于路由事件的示例,该规则可能会说它的类型被“标记”为 beeing routed,因为它的名称带有“Routed”一词。虽然事件的命名本身表明名称以“预览”开头。

        正如我所提到的:这只是我的意见,所以不要怪我;)

        【讨论】:

        • sender 参数肯定有它的用途。每当您将相同的处理程序绑定到多个对象上的事件时,它就会发挥作用。虽然它并非一直有用,但使用您的代码的人希望它可用。至于EventArgs 的后代的使用,我个人认为这促进了在您的代码和用户的代码之间设置一个门的想法 - 确保您不会意外地给他们一个您不希望他们修改的可变对象等。不过,您关于命名的评论绝对有效。让我希望 C# 有 typedef...
        猜你喜欢
        • 1970-01-01
        • 2010-09-23
        • 2013-07-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多