我有以下方法:
void Add<T>(T entity) where T : class;
void Add<T>(IEnumerable<T> entities) where T : class;
我有以下课程:
public class MimeTable : List<Mime> { }
然后我尝试按如下方式使用它:
Add(new MimeTable())
我收到错误,因为它被称为第一个Add方法,而不是第二个。
应该被称为第二个,因为MimeTable是一个List?
有没有办法解决这个问题?
答案 0 :(得分:3)
在这种情况下,第二次Add
重载几乎不可能被实际调用。您必须调用它的唯一方法是使用反射或使用命名参数(因为参数名称不同),这两种方法都不是特别实用。
这是由于过载分辨率的更好算法。过载更好&#34;如果它不需要隐式转换而另一个需要隐式转换,则比另一个。一旦推断出泛型参数,您的第一个重载就是接受MimeTable
类型的参数,这是参数的确切类型。第二个重载是接受需要隐式转换的IEnumerable<Mime>
。那种超负荷会更糟糕&#34;永远不会出现那种过载会更好的情况&#34;。
最方便的选择几乎肯定会在这里使用两种不同的方法,而不是重载单个方法。除了键入不同的名称之外,任何其他区分它们的方法都会更有效。
答案 1 :(得分:0)
就像其他人说过的那样,你可能想要将第二个Add
方法重命名为AddRange
或者你喜欢的东西。如果出于某种原因,您确实希望在传递List时实现备用功能,则可以重命名第二个Add
方法,并在第一个Add
方法的开头添加一个检查,其中包含: / p>
if (entity is IList)
{
AddRange(entity);
return;
}
答案 2 :(得分:0)
您还可以投射您的MimeTable
到IEnumerable<Mime>
,然后调用第二个重载。这段代码:
class Mime
{
}
class MimeTable : List<Mime>
{
}
class Widget
{
public void Add<T>( T entity ) where T:class
{
Console.WriteLine("Add/1 overload #1" ) ;
}
public void Add<T>( IEnumerable<T> entity ) where T:class
{
Console.WriteLine( "Add/2 overload #2" ) ;
}
}
class Program
{
static int Main( string[] args )
{
MimeTable mt = new MimeTable() ;
Widget widget = new Widget() ;
widget.Add( mt ) ;
widget.Add( (IEnumerable<Mime>) mt ) ;
return 0 ;
}
} // program
生成此输出:
Add/1 overload #1
Add/2 overload #2
但是如上所述,为什么不重命名方法以明确意图呢?