继承对象列表的类

时间:2014-10-08 16:53:17

标签: c#

我有以下方法:

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?

有没有办法解决这个问题?

3 个答案:

答案 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)

您还可以投射您的MimeTableIEnumerable<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

但是如上所述,为什么不重命名方法以明确意图呢?