C# Cannot convert from IEnumerable<Base> to IEnumerable

后端 未结 4 571
忘掉有多难
忘掉有多难 2020-12-19 07:53

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 expec

相关标签:
4条回答
  • 2020-12-19 08:17

    In C# 3.0 you can use the "Cast" extension method. If you import System.Linq and then use this code:

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

    Then it should work for you.

    0 讨论(0)
  • 2020-12-19 08:19

    There is workaround with extension method:

    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>() );
    

    but the "<Person, Employee>" is little bit awkward :/.

    0 讨论(0)
  • 2020-12-19 08:33

    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.

    0 讨论(0)
  • 2020-12-19 08:36

    The cast solution of course might generated class cast exceptions. The person who posted the enumerable extension work around said it was awkward. I came up with a solution which is only half as awkward, don't know if I'll use it:

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

    Usage:

    IEnumerable mammals = UpTo<Mammal>.From(kennel.Dogs)

    0 讨论(0)
提交回复
热议问题