I have a set up like this:
abstract class Foo {}
class Bar : Foo {}
and a method elsewhere of this form:
void AddEntries(List&l
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
{
}
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.
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.