首先,我正在阅读一些论坛和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声明,而不仅仅是一两个声明。
答案 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);
}