我想知道为什么不允许通用重载,并且导致编译器错误“模糊”分辨率。
以下是示例代码:
class Program
{
static void Main(string[] args)
{
var p = new Program();
p.DoWork(new First());
p.DoWork(new Second());
p.DoWork(new Multi()); //ambiguous: that's right!
p.Test<IFirst>(new First()); //ambiguous???
}
private void DoWork(IFirst arg) { }
private void DoWork(ISecond arg) { }
private void Test<T>(T arg) where T : IFirst { }
private void Test<T>(T arg) where T : ISecond { }
}
interface IFirst { }
interface ISecond { }
class First : IFirst { }
class Second : ISecond { }
class Multi : IFirst, ISecond { }
在显式声明要考虑的接口之后,我无法感觉到显式形式(DoWork)和通用形式之间的区别。为什么第一个允许,第二个不允许?
我的目标是让两个“测试”方法表现得相似但不完全正确。
任何解决方法(除了以不同方式命名方法)?
提前谢谢大家。
答案 0 :(得分:6)
答案 1 :(得分:0)
即使没有对方法进行任何调用,此代码也无法编译。这里的问题是,由于泛型类型约束不是方法签名的一部分,因此两个Test<T>
声明具有相同的签名:
private void Test<T>(T arg) where T : IFirst { }
private void Test<T>(T arg) where T : ISecond { }
由于以下原因也无法编译,因此无法编译:
private void Foo() { }
private void Foo() { }
编译器会抱怨已经声明了具有相同签名的方法。
请注意,DoWork
方法没有此问题:
private void DoWork(IFirst arg) { }
private void DoWork(ISecond arg) { }
由于参数类型是方法签名的一部分,这里我们讨论一种方法的两个标准重载,这是完全可以的。