我可以定义具有相同名称但不同参数的2个代理吗?

时间:2013-06-10 16:10:40

标签: c# .net delegates overloading

我尝试在Int32IntPtr之间定义委托覆盖。为什么以下过载是非法的?

public delegate int EnumWindowsCallback (System.IntPtr hWnd, int lParam);

public delegate int EnumWindowsCallback (System.IntPtr hWnd, System.IntPtr lParam);

这看起来很奇怪。它们都是结构但不同,并且从不同的接口实现。

想想看,我以前从未尝试过代表委托。它甚至是合法的,如果是的话,为什么?

更新:在完成答案和更多SO帖子后,我感到困惑的是,即使使用不同数量的参数也无法声明代理人。我仍然想知道为什么在运行时无法解决这个问题。

4 个答案:

答案 0 :(得分:9)

  

想想看,我以前从未尝试过代表委托。它甚至是合法的,如果是的话,为什么?

不,这不合法。您目前正在使用相同的完全限定名称声明两个类型

看起来的唯一一点就是在类型方面有点像重载,如果你声明两种类型,它们的泛型类型参数的数量不同。例如,Action<T>Action<T1, T2>等。代表的规则与此处其他类型的规则没有什么不同。

因此,您需要声明一个通用委托(并使用不同的类型参数),或使用两个不同的类型名称。

答案 1 :(得分:4)

不,你不能重载委托。当有类型信息可供编译器选择时,选择重载...但是使用委托,提供类型信息,编译器无法从重载中选择。

如果您想要一个类似委托类型的系列,可以使用泛型。

public delegate int EnumWindowsCallback<LParamType>(System.IntPtr hWnd, LParamType lParam);

现在您可以定义重载的p / invoke签名,它们接受不同的委托类型EnumWindowsCallback<int>EnumWindowsCallback<IntPtr>等。

答案 2 :(得分:2)

所有委托类型仅限于一种.Invoke方法。我不确定如果使用CIL来定义一个派生自Delegate并包含多个Invoke重载的类型,那么框架究竟会做什么,但期望只有一个Invoke将存在的方法很好地支持到Framework中。

然而,可以做的是定义一个可以代替委托类型使用的接口。例如,可以定义类似的内容:

interface IInvokableAsOptionalGeneric
{
  void Invoke();
  void Invoke<T>(T param);
}

在这种情况下,对具有InvokableAsOptionalGeneric实现内容的引用的代码可以在没有参数的情况下调用它,也可以使用任何类型的参数调用它;后一种形式可以与值类型参数一起使用而不需要装箱(而Action<Object>必须将参数包装起来)。请注意,对于上述样式的任何接口,可以使用类似于Delegate.Combine的静态方法定义一个类,该类可以与实现该接口的任何对象一起使用;每个这样的接口都需要自己的“组合”类,尽管很多代码都是样板文件。

答案 3 :(得分:2)

我不喜欢那些总是说“不,你不能”的人。 ;-)
因此我的答案是:是的,你可以!

最初我想从泛型方法调用重载的非泛型方法。编译器不喜欢这样。可能的解决方案在SO 5666004SO 3905398,但我发现它们非常复杂。

在阅读了这篇文章以及其他帖子和文章之后,我心里想到了一些模糊的想法。试错,并学习新功能让我找到了一个有效的解决方案。

其他是正确的,你不能重载正常的委托,因为每个委托都有它的个人类型并使用静态绑定。
但是您可以使用抽象的df1 <- structure(list(chr = c("chr1", "chr1", "chr1", "chr1", "chr1", "chr1", "chr1", "chr1"), ID1 = c(11046L, 18615L, 27209L, 35274L, 36589L, 43655L, 49265L, 50117L), ID2 = c(12418L, 19392L, 28559L, 35492L, 38097L, 45148L, 50054L, 50465L), val = c(2L, 2L, 3L, 1L, 2L, 2L, 2L, 1L), Col = c("E-H3K27ac,D-Both", "D-Both,E-Both", "E-H3K4me1,D-Both,E-Both", "E-H3K4me1", "D-Both,E-Both", "D-Both,E-Both", "D-Both,E-H3K4me1", "E-H3K4me1")), .Names = c("chr", "ID1", "ID2", "val", "Col"), class = "data.frame", row.names = c(NA, -8L)) 类和动态绑定。

这是准备编译并运行的解决方案(用C ++ / CLI编写):

Delegate