How to pass List of class to List of Interface?
I have a function like this:
DoSomething(List<IMyInterface>)
IMyInterface is an int开发者_如何学Pythonerface and MyClass is a class implementing this interface Class MyClass:IMyInterface
I call DoSomething(List<MyClass>)
and it looks it doesn't work.
How could I pass the list of a class to a list of the interface of the class as function's parameter? Thanks!
If your code is simply iterating over the sequence inside the method (not adding, removing, or accessing by index), change your method to one of the following
DoSomething(IEnumerable<IMyInterface> sequence)
DoSomething<T>(IEnumerable<T> sequence) where T : IMyInterface
The IEnumerable<>
interface is covariant (as of .NET 4) (first option). Or you could use the latter signature if using C# 3.
Otherwise, if you need indexed operations, convert the list prior to passing it. In the invocation, you might have
// invocation using existing method signature
DoSomething(yourList.Cast<IMyInterface>().ToList());
// or updating method signature to make it generic
DoSomething<T>(IList<T> list) where T : IMyInterface
What the latter signature would allow you to do is to also support adds or removes to the list (visible at the callsite), and it would also let you use the list without first copying it.
Even still, if all you do is iterate over the list in a loop, I would favor a method acceping IEnumerable<>
.
This is not safe in general because Lists are mutable. Suppose you pass someone a reference to a List<MyClass>
as a List<IMyInterface>
, then they do:
void Foo(List<IMyInterface> list)
{
IMyInterface x = new MyOtherClassWhichAlsoImplementsIMyInterface();
list.Add(x);
}
Now your List<MyClass>
contains an instance of a class that is not a MyClass
. This would violate type safety. (As other answers noted, you can avoid this problem by passing only the IEnumerable<>
interface of List, which provides read-only access and so is safe).
For more details, see Using Variance in Interfaces for Generic Collections on MSDN. See also a good summary of covariance and contravariance and various C# features that support it.
If you only need to go through the list, declare the method with an IEnumerable. If you want to add elements to the list, what you're asking isn't typesafe and might not be allowed in C# as a result.
精彩评论