泛化委托代码(C#)

4
我有两个非常相似的类,它们基本上做相同的事情。唯一的区别在于提供给每个类的回调处理程序。回调处理程序是不同的,并且接受不同的参数。我想将这些类中的大部分代码概括为一个基类。有没有关于如何智能地概括委托代码的想法?我使用的是.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()
}

2
协变性和逆变性在.NET 4.0之前非常有限。这是泛型类型的协变性和逆变性主要支持出现的时候。 - James Michael Hare
3
你能否在大部分通用代码中添加一些关于委托和处理程序如何被调用的细节?我想到了定义抽象的OnRaise()事件,并由基类调用,但在A和B中进行重写和实现以便使用委托和处理程序来完成正确的任务。但在不了解更多信息的情况下,我还不能确定是否可行。 - n8wrl
1个回答

5
为什么不这样设置:
编辑:我已更新,包括你的编辑方法。
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
@kateroh - 所以 StartListening 是相同的,但是 CheckForChanges 取决于委托方法的签名/调用? - Richard Marskell - Drackir
是的。在这两个类中,其他方法也是一样的。 - kateroh
@kateroh - 看到我的编辑了吗?我认为那应该解决了你的问题。 - Richard Marskell - Drackir
另外,我非常推荐阅读这本书:Head First设计模式。它是基于Java的,但代码示例简单易懂,通常可以轻松转换为C#。它详细介绍了不同的设计问题,并概述了经过验证的解决方法。而且它也很容易阅读。 :) - Richard Marskell - Drackir

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接