我最近遇到麻烦的时候,试图AddRange(综合),一个列表。可能是一个经典的问题,但是我真的不得到它。

我明白,方法期待一个列表中的参数不满意的一个列表,因为他们可能尝试增加一个基本列表,这显然是不可能的。

但如果我得到这正确的,因为IEnumerables自己无法改变的,它应该来工作,在这种情况。

代码我认为是这样的:

class Foo
{
}

class Bar : Foo
{
}

class FooCol
{
    private List<Foo> m_Foos = new List<Foo> ();

    public void AddRange1(IEnumerable<Foo> foos)
    {
        m_Foos.AddRange (foos); // does work
    }

    public void AddRange2<T>(IEnumerable<T> foos) where T : Foo
    {
        m_Foos.AddRange (foos); // does not work
    }
}

class Program
{
    static void Main(string[] args)
    {
        FooCol fooCol = new FooCol ();

        List<Foo> foos = new List<Foo> ();
        List<Bar> bars = new List<Bar> ();

        fooCol.AddRange1 (foos); // does work
        fooCol.AddRange1 (bars); // does not work

        fooCol.AddRange2 (foos); // does work
        fooCol.AddRange2 (bars); // does work
    }
}

我试图通过一个提示来编译器在AddRange2方法,但是,这只是转移问题的周围。

是我的思维方式有缺陷的?这一限制语言,或是通过设计?

请参考,支持这种行动加入Java1.5,因此也许它会被添加到C#在某一点在未来,太...?

有帮助吗?

解决方案

这是协,并将其固定在C#4.0/.净4.0.现在,一般的选择是最好的答案(对 IEnumerable<T> - IList<T> 等等).

但在通用的方法,则必须考虑的 T.你也可以使用 Cast<T>OfType<T> 与皇宫实现类似的东西。

其他提示

在C#3.0则可以使用“铸”扩展方法。如果您导入System.Linq的,然后使用此代码:

public void AddRange2<T>(IEnumerable<T> foos) where T : Foo
{
    m_Foos.AddRange (foos.Cast<Foo>());
}

然后,它应该为你工作。

有替代方法是用扩展方法:

public static IEnumerable<TBase> ToBaseEnumerable<TBase, TDerived>( this IEnumerable<TDerived> items ) where TDerived : TBase {
    foreach( var item in items ) {
        yield return item;
    }
}
...
IEnumerable<Employee> employees = GetEmployees(); //Emplyoee derives from Person
DoSomethingWithPersons( employees.ToBaseEnumerable<Person, Employee>() );

但 “<人,雇员>” 是有点笨拙:/

当然,浇注溶液可能产生类转换异常。 谁张贴周围的枚举推广工作的人说,这是尴尬。 我想出了一个解决方案,它是只有一半的尴尬,不知道我是否会使用它:

public static class UpTo<T>
{
    public static IEnumerable<T> From<F>(IEnumerable<F> source) where F:T
    {
        // this cast is guaranteed to work
        return source.Select(f => (T) f);
    }
}

用法:

IEnumerable的哺乳动物=高达<哺乳动物>。从(kennel.Dogs)

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top