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

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

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

 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."); } 

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

Action类“执行此操作”。 它是一个带模板的委托,所以你可以拥有这样一个委托:

 public delegate void D(params T[] arg); func() { D d1; } 

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

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

 public void bar() { D d = ...; fire(d, "first", "second"); fire(d); // also works } public void fire(D f, params T[] args) { f(args); }