Cannot convert from List<Bar> to List<Foo>

无人久伴 提交于 2019-12-31 09:57:05

问题


I have a set up like this:

abstract class Foo {}
class Bar : Foo {}

and a method elsewhere of this form:

void AddEntries(List<Foo>) {}

I am trying to call this method using a list of objects of type Bar

List<Bar> barList = new List<Bar>()
AddEntries(barList);

but this gives me the error:

cannot convert from List<Bar> to List<Foo>

Is there anyway around this problem? I Need to keep the method definition using the abstract class.


回答1:


You could make your AddEntries generic and change it to this

void AddEntries<T>(List<T> test) where T : Foo
{
    //your logic 
}

Have a look at Constraints on Type Parameters for further information.




回答2:


Have a read of Covariance and Contravariance in Generics from docs.microsoft.com as this, particularly the section "Generic Interfaces with Covariant Type Parameters" will cover off the scenario that you're working with.

In short, if you (can) change the signature of your AddEntries method to:

static void AddEntries(IEnumerable<Foo> entries)

(Note the use of IEnumerable<Foo> instead of List<Foo>) you'll be able to do what you're looking to do.

The specific difference here is that the IEnumerable<T> and List<T> are declared differently:

public interface IEnumerable<out T> : IEnumerable
public class List<T> : IList<T>, ... ...

The difference that matters is the out in the declaration of IEnumerable<T> which indicates that it is covariant which means (with the definition taken from docs.microsoft.com):

Covariance: Enables you to use a more derived type than originally specified.




回答3:


This is not allowed for a simple reason. Assume the below compiles:

AddEntries(new List<Bar>());

void AddEntries(List<Foo> list)
{
   // list is a `List<Bar>` at run-time
   list.Add(new SomethingElseDerivingFromFoo()); // what ?!
}

If your code would compile, you have an unsafe addition (which makes the whole generic lists pointless) where you added SomethingElseDerivingFromFoo to actually a List<Bar> (runtime type).

To solve your problem, you can use generics:

void AddEntries<T>(List<T> list) where T:Foo
{

}


来源:https://stackoverflow.com/questions/45349582/cannot-convert-from-listbar-to-listfoo

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!