我尝试在Int32
和IntPtr
之间定义委托覆盖。为什么以下过载是非法的?
public delegate int EnumWindowsCallback (System.IntPtr hWnd, int lParam);
public delegate int EnumWindowsCallback (System.IntPtr hWnd, System.IntPtr lParam);
这看起来很奇怪。它们都是结构但不同,并且从不同的接口实现。
想想看,我以前从未尝试过代表委托。它甚至是合法的,如果是的话,为什么?
更新:在完成答案和更多SO帖子后,我感到困惑的是,即使使用不同数量的参数也无法声明代理人。我仍然想知道为什么在运行时无法解决这个问题。
答案 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 5666004和SO 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