【问题标题】:Generalizing delegate code (C#)泛化委托代码 (C#)
【发布时间】:2011-05-13 17:47:38
【问题描述】:

我有两个非常相似的类,它们基本上做同样的事情。唯一的区别在于提供给每个类的实例的回调处理程序。回调处理程序是不同的,它们接受不同的参数。我想将这些类中的大部分代码概括为一个基类。关于如何智能地概括委托代码的任何想法?我在 .NET 2.0 上

注意:我阅读了 this 非常有用的关于委托继承的博客以及关于委托协变和逆变的文章,但我仍然不知道如何在这里应用这些知识。


public class A
{
    public delegate void AHandler(string param1, string param2);
    public void AcceptHandler(string param3, AHandler handler);
    public void InvokeHandler(string forParam1, string forParam2);

    // the rest is same
}

public class B
{
    public delegate void BHandler(int param1);
    public void AcceptHandler(int param2, int param3, int param4, BHandler handler);
    public void InvokeHandler(int forParam1);

    // the rest is same
}

编辑: 代码的“其余部分”完全相同,除了调用具有不同签名的委托方法。像这样的:


public void StartListening()
{
   Timer timer = new Timer(CheckForChanges, null, 0, 1000);            
}

private void CheckForChanges()
{
    // pull changes, and pass different params to InvokeHandler()
}

【问题讨论】:

  • 在 .NET 4.0 之前,协变和逆变是非常有限的。这就是泛型类型的协变和逆变的主要支持出现的时候
  • 你能补充一些关于委托和处理程序如何被最常见的代码调用的细节吗?我正在考虑由基定义和调用的某种抽象 OnRaise() 事件,但在 A 和 B 中被覆盖和执行以对委托和处理程序做“正确的事情”,但我不确定不知道更多

标签: c# delegates .net-2.0 c#-2.0


【解决方案1】:

为什么不这样设置:
编辑:我已更新以包含您编辑的方法。

public abstract class AbstractBase {
    // "the rest"
    public void StartListening() {
        Timer timer = new Timer(CheckForChanges, null, 0, 1000);            
    }
    protected abstract void CheckForChanges();
}

public class A : AbstractBase {
    public delegate void AHandler(string param1, string param2);
    public void AcceptHandler(string param3, AHandler handler);
    public void InvokeHandler(string forParam1, string forParam2);
    protected override void CheckForChanges() {
        //Do stuff for this version of the class
    }
}

public class B : AbstractBase {
    public delegate void BHandler(int param1);
    public void AcceptHandler(int param2, int param3, int param4, BHandler handler);
    public void InvokeHandler(int forParam1);
    protected override void CheckForChanges() {
        //Do stuff for this version of the class
    }
}

这样,您将在单个类中拥有相同的所有代码,然后各个类 AB 可以具有您需要的任何形式的方法。

或者您是否正在寻找一种方法来通用地调用委托而不考虑哪个类?

即。比如:

AbstractBase ab = new A();
ab.InvokeDelegate();

【讨论】:

  • 是的,概括委托代码会很好,因为代码的“其余部分”是相同的,除非使用委托相关的东西(见编辑)。
  • @kateroh - 所以StartListening 是一样的,但CheckForChanges 取决于委托方法签名/调用?
  • 是的。与两个类中的其他方法相同。
  • @kateroh - 查看我的编辑。我认为这应该解决您的编辑问题。
  • 另外,我真的推荐看看这本书:Head First Design Patterns 它是基于 Java 的,但代码示例很简单,通常很容易转换为 C#。它完全像这样讨论了不同的设计问题,并概述了解决这些问题的久经考验的方法。它也很容易阅读。 :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-02-27
  • 1970-01-01
相关资源
最近更新 更多