C# - 如何“重载”代理?

时间:2010-09-19 23:50:33

标签: c# delegates overloading

首先,我正在阅读一些论坛和MSDN中的帮助,所有人都说代理人不能超载。

现在,我想要这样的事情:

public delegate void OneDelegate();
public delegate void OneDelegate(params object[] a);

public void DoNothing(params object[] a) {}
public void DoSomething() { /* do something */ }

private OneDelegate someFunction;

someFunction = new OneDelegate(DoSomething);
someFunction = new OneDelegate(DoNothing);

所以,就像你知道的那样,你不能这样做,因为OneDelegate只引用第一个而不是第二个。但是,有没有办法做到这一点?或类似的东西?

PS1:我希望拥有任意数量的OneDelegate声明,而不仅仅是一两个声明。

2 个答案:

答案 0 :(得分:35)

想象一下这是可能的。假设我可以有一个重载的委托:

public delegate void OneDelegate(int i);
public delegate void OneDelegate(string s);

现在假设我声明了这种类型的变量,然后为它分配一个函数,例如:

OneDelegate myDelegate = StringMethod;

因此声明StringMethod

public void StringMethod(string s) { Console.WriteLine(s); }

现在您将myDelegate传递给其他代码,该代码执行此操作:

myDelegate(47);

在这种情况下,您期望发生什么?运行时如何使用整数参数调用StringMethod()

如果你真的想要一个可以任何参数集的委托,那么唯一的选择就是拥有一个params object[]数组:

public delegate void OneDelegate(params object[] parameters);

但是你必须为它分配一个实际上可以处理任何对象数组的函数,例如:

public void MyMethod(params object[] parameters)
{
    if (parameters == null || parameters.Length == 0)
        throw new ArgumentException("No parameters specified.");
    if (parameters.Length > 1)
        throw new ArgumentException("Too many parameters specified.");

    if (parameters[0] is int)
        IntMethod((int) parameters[0]);
    else if (parameters[0] is string)
        StringMethod((string) parameters[0]);
    else
        throw new ArgumentException("Unsupported parameter type.");
}

正如你所看到的,这很快就会变得混乱。因此,我向您提出,如果您需要这样的代表,您可能在您的建筑设计中的某个地方犯了一个错误。在继续实施之前确定此缺陷并修复设计,否则代码的可维护性将受到影响。

答案 1 :(得分:7)

Action类“这样做”。它是一个带模板的委托,因此您可以拥有这样的委托:

public delegate void D<T>(params T[] arg);

func() {
    D<object> d1;
}

这可能与您将要获得的一样接近,即您需要模板类型作为参数。

编辑:根据评论,我猜你是在将一个委托传递给另一个函数之后。您也可以通过传递参数来完成它。遗憾的是,如果不使用fire的参数参数,则无法执行此操作。

public void bar() {
    D<string> d = ...;
    fire(d, "first", "second");
    fire(d); // also works
}

public void fire<T>(D<T> f, params T[] args) {
    f(args);
}