如果我选择不同的通用限制,为什么不能使用相同的参数重载方法?

时间:2011-03-19 02:34:41

标签: c# .net generics c#-4.0 overloading

如果我在c#4.0 .NET中执行此操作

    private static void myMethod<T>(int obj) where T : IDictionary
    {


    }

    private static void myMethod<T>(int obj) where T : ICollection
    {


    }

我收到以下错误。

  

类型   'ConsoleApplication1.Program'已经   定义一个名为'myMethod'的成员   使用相同的参数   类型

我想知道为什么?据我所知,这两种方法都可以毫无歧义地调用吗?

如果我想要第一种方法,我会这样做

myMethod<IDictionary>(50)

和第二种方法

myMethod<ICollection>(40)

我错过了什么情景?有没有办法实现一组具有相同参数但不同类型的重载方法?

3 个答案:

答案 0 :(得分:9)

C#中的重载分辨率根本不考虑约束。

来自C#规范:

  

7.5.3过载分辨率

     

重载解析是一种绑定时机制   用于选择最佳功能成员   调用给定参数列表和一组候选函数成员

@Anthony Pegram的博客链接是关于这个主题的更好的阅读: Constraints are not part of the signature

答案 1 :(得分:2)

重载仅基于功能参数。返回类型和模板参数(更具体地说:约束)不适用于重载函数。我不能告诉你为什么会这样(因为我没有写这种语言,也没有假装理解他们所有的担忧)。我只能告诉你编译器会允许什么。

您可能希望重载约束的一个原因可能是尝试完成C ++模板特化的等效。不幸的是,C#不支持这一点。 .Net泛型和C ++模板是非常不同的野兽。

关于你的具体例子;有两种方法可以解决这个问题。两者都要求你以不同的方式思考你的问题。

真正的问题是你想要的用法会伤害你的设计。重载实际上只是语法糖。重载可帮助人们调用您的公共界面。它实际上并没有帮助你内部。实际上,如果重载方法做了很多不同的事情,那么在调试代码时,以及当你必须返回并维护代码时,可能会更难以推理代码。

由于调用这些函数的代码必须指定T,因此您不会通过重载函数来节省任何维护成本。相反,您可以考虑将依赖项(集合)注入这些方法。

private static void myMethod(int obj, IDictionary dictionary)
{
    // do something with the dictionary here, setting private members while you do it
}

private static void myMethod(int obj, ICollection collection)
{
    // do something with the collection here, setting private members while you do it
}

如果此解决方案要求您经常复制new Dictionarynew List调用,或者您希望方法控制实例创建的时间,则可以放弃重载。

private static void myMethodWithDictionary<T>(int obj) where T : IDictionary, new()
{
    // Create your new dictionary here, populate it, and set internal members
}

private static void myMethodWithCollection<T>(int obj) where T : ICollection, new()
{
    // Create your new collection here, populate it, and set internal members
}

答案 2 :(得分:1)

如果您的课程为public class Whatever : IDictionary, ICollection,会怎样?编译器不知道要使用哪个重载。