C#无法从IEnumerable转换< Base>到IEnumerable< Derived> [英] C# Cannot convert from IEnumerable<Base> to IEnumerable<Derived>

查看:116
本文介绍了C#无法从IEnumerable转换< Base>到IEnumerable< Derived>的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我最近遇到麻烦,当尝试AddRange(IEnumerable)到一个列表。



我理解,期望List参数的方法不能满足列表,因为他们可能尝试添加



但是如果我得到这个正确,因为IEnumerables本身不能改变,它应该在这种情况下工作。

p>

我认为代码看起来像这样:

  class Foo 
{
}

class Bar:Foo
{
}

class FooCol
{
private列表< 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)其中T:Foo
{
m_Foos.AddRange(foos); //不工作
}
}

类程序
{
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); //不工作

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



我尝试传递一个提示编译器在AddRange2方法,但这只是转移到问题。



我的思维方式有缺陷吗?这是对语言的限制还是由设计?



IIRC,对这种操作的支持被添加到Java 1.5,因此也许它将被添加到C#

$ p

解决方案

这是协方差,将在C#4.0 /中修复。 NET 4.0。现在,通用选项是最好的答案( IEnumerable< T> - IList< T> )。



但是在通用方法中,你必须考虑 T 。您也可以使用LINQ来使用 Cast< T> OfType< T>

I recently run into trouble when trying to AddRange(IEnumerable) to a List. Probably a classic issue, but I do not really get it yet.

I understand that methods expecting a List parameter are not satisfied with a List, because they might try to add a Base to the List, which is obviously impossible.

But if i get this correctly, since IEnumerables themselves cannot be changed, it ought to work in this case.

The code i thought of looks like this:

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
    }
}

I tried to pass a hint to the compiler in the AddRange2 method, but this just moved to problem around.

Is my way of thinking flawed? Is this a limitation of the language or is it by design?

IIRC, support for this kind of operations was added to Java 1.5, so maybe it will be added to C# at some point in the future, too...?

解决方案

This is covariance, and will be fixed in C# 4.0 / .NET 4.0. For now, the generic option is the best answer (for IEnumerable<T> - not IList<T> etc).

But within the generic method, you have to think in terms of T. You could also use Cast<T> or OfType<T> with LINQ to achieve something similar.

这篇关于C#无法从IEnumerable转换&lt; Base&gt;到IEnumerable&lt; Derived&gt;的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆