Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/330.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 为什么泛型重载结果不明确?_C#_Generics_Overloading - Fatal编程技术网

C# 为什么泛型重载结果不明确?

C# 为什么泛型重载结果不明确?,c#,generics,overloading,C#,Generics,Overloading,我想知道为什么不允许泛型重载,它会导致编译器错误的“不明确”解决方案 以下是示例代码: 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

我想知道为什么不允许泛型重载,它会导致编译器错误的“不明确”解决方案

以下是示例代码:

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 { }
类程序
{
静态void Main(字符串[]参数)
{
var p=新程序();
p、 道工(新的第一个());
p、 道克(新第二个());
p、 DoWork(新的Multi());//暧昧:没错!
p、 Test(newfirst());//不明确???
}
私有无效DoWork(IFirst arg){}
私有空嫁妆(等秒arg){}
私有无效测试(T arg),其中T:IFirst{}
私有无效测试(T arg),其中T:ISecond{}
}
接口IFirst{}
接口等秒{}
第一类:IFirst{}
第二类:等秒{}
类多:IFirst,ISecond{}

我没有感觉到显式表单(DOWORK)和泛型表单之间的区别,已经显式声明了要考虑的接口。为什么第一个允许而第二个不允许

我的目标是让两个“测试”方法表现相似,但并不完全相同

有什么解决方法(除了以不同的方式命名方法之外)


提前谢谢大家。

即使不调用任何方法,此代码也无法编译。这里的问题是,由于泛型类型约束不是方法签名的一部分,因此两个
Test
声明具有相同的签名:

private void Test<T>(T arg) where T : IFirst { }

private void Test<T>(T arg) where T : ISecond { }
编译器会抱怨已经声明了具有相同签名的方法

请注意,
DoWork
方法没有此问题:

private void DoWork(IFirst arg) { }

private void DoWork(ISecond arg) { }

由于参数类型是方法签名的一部分,因此这里我们讨论的是一个方法的两个标准重载,这是完全正确的。

即使不调用任何方法,此代码也不会编译。这里的问题是,由于泛型类型约束不是方法签名的一部分,因此两个
Test
声明具有相同的签名:

private void Test<T>(T arg) where T : IFirst { }

private void Test<T>(T arg) where T : ISecond { }
编译器会抱怨已经声明了具有相同签名的方法

请注意,
DoWork
方法没有此问题:

private void DoWork(IFirst arg) { }

private void DoWork(ISecond arg) { }

由于参数类型是方法签名的一部分,这里我们讨论的是一个方法的两个标准重载,这是完全正确的。

OK。这篇文章解释了这些限制,尽管我正在努力理解为什么不能解决这些问题。然而,从我的样本观点来看,它看起来确实很奇怪:如果只尝试“考虑”泛型,编译器就不应该解决正确的方法。它看起来更像是一个编译器限制,而不是一个无法解决的问题。当然不是一个bug。@Mario:当然有可能解决这个问题。这是一个设计决定,像这样实施它。好的。这篇文章解释了这些限制,尽管我正在努力理解为什么不能解决这些问题。然而,从我的样本观点来看,它看起来确实很奇怪:如果只尝试“考虑”泛型,编译器就不应该解决正确的方法。它看起来更像是一个编译器限制,而不是一个无法解决的问题。当然不是一个bug。@Mario:当然有可能解决这个问题。这是一个设计决策,像这样实施它。