【问题标题】:Action<T> vs virtual methodsAction<T> 与虚拟方法
【发布时间】:2012-06-20 15:18:34
【问题描述】:

假设我有一个游戏创建框架,有一个名为 Game 的基本类。

// Action version
public class Game 
{
    public Action<float> OnUpdate;
    public void Update(float mFrameTime) { OnUpdate.Invoke(mFrameTime); }
}

// Virtual version
public class Game 
{
    public virtual void Update(float mFrameTime) {}
}

哪一个是最好的方法? (设计方面和性能方面)

为 OnUpdate 操作订阅某些内容(而不是继承 Game 类),还是继承 Game 类并覆盖虚拟方法?

【问题讨论】:

  • 仅供参考 xna 框架使用虚拟方法。除非您的用例不同,否则我个人会相信他们的判断。 :)

标签: c# .net lambda virtual


【解决方案1】:

这取决于Update 通知的目标受众。如果它仅用于派生类,那么 virtual 方法是一个很好的方法。如果它用于派生类和/或任意消费者,那么事件样式模式是正确的方法。

【讨论】:

    【解决方案2】:

    我宁愿引发事件也不愿拥有Action&lt;T&gt;。这是 .NET 中的常见模式:

    public class Game 
    {
        public event EventHandler<SomeEventArgs> Update;
        protected virtual void OnUpdate(float mFrameTime) { // invoke event here }
    }
    

    【讨论】:

    • 引发事件而不是使用动作究竟有什么优势?
    • 事件是委托(有访问限制)。没有差异。代表也可以有多个订阅者(试试看:)。设计方面,事件通常用于良好,事件和普通委托通常用于回调。 [编辑:强调事件是委托——它们是完全相同的东西,它是一个别名,对访问有一些额外的编译器限制——如果你愿意,你可以得到添加/删除道具)
    【解决方案3】:

    这取决于你的框架的其余部分是什么样的,以及你打算用这个类做什么。如果这个类只是提醒其他类该更新了,那么您将需要一个基于事件的系统。如果这是所有游戏派生的基类,那么您可能需要一个覆盖。没有一个答案是 100% 正确的 - 这完全取决于您想要通过设计完成什么。

    【讨论】:

      【解决方案4】:

      很遗憾,我不知道从性能的角度来看,哪些选项更有效,但从设计的角度来看,我建议重写 Update 方法,原因如下:

      1. 它将您的所有更新逻辑集中在一个位置。
      2. 它允许您轻松监控更新操作的顺序。

      正如其他人所说,这取决于课程的目的,我基于这是一个“游戏”课程这一事实做出假设。没有理由不能使用触发事件的虚拟方法来实现两者。这将允许集中定位大部分更新代码,并允许元素根据需要订阅更新事件。

      当我自己处理同样的问题时,我通常采用虚拟方法方法,但为了方便和控制目的,我将更新分解为多个部分。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-06-13
        • 2013-10-23
        • 2013-05-01
        • 1970-01-01
        • 2011-06-13
        • 2021-12-04
        相关资源
        最近更新 更多