如果我在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)
我错过了什么情景?有没有办法实现一组具有相同参数但不同类型的重载方法?
答案 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 Dictionary
或new 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
,会怎样?编译器不知道要使用哪个重载。