I have an interface and 2 classes inheriting that interface like below
public interface ILeader
{
int ID { set; get; }
string Name { set; get; }
}
public class User : ILeader
{
public int ID { set; get; }
public string Name { set; get; }
}
public class Group : ILeader
{
public int ID { set; get; }
public string Name { set; get; }
}
Now i have 2 method which has a parameter of type ILeader
and IList of ILeader
public void Change(ILeader leader)
{
//do some thing
}
public void ChangeList(IList<ILeader> leaderList)
{
//do some thing
}
now i can pass an object of either Group
or User
to Change method and it works. But when i try to do the same with a List
to ChangeList
method it gives me compile time error.
IList<User> userList=new List<User>();
userList.Add(new User { ID=1, Name ="Happy"});
Change(userList[0]); //this works
ChangeList(userList); //this throws compile error
The error is
cannot convert from List<User> to List<ILeader>
How to make my ChangeList
method work so that i can pass both a list of Users
and Groups
?
If you are using .Net 4.0 or greater, you can change your IList(T) to an IEnumerable(T) and it will work. The IList(T) interface's T parameter is not covariant and IEnumerable(T) interface's T parameter is. See
http://msdn.microsoft.com/en-us/library/dd469487.aspx
for further explanation.
Because IList<T>
is not covariant, which means there's nothing from stopping ChangeList
from adding a Group
to the list of Users
, which is obviously invalid.
To pass a list of both kinds, convert the list to a List<ILeader>
:
ChangeList(userList.Cast<ILeader>().ToList());
However be aware that this doesn't actually cast the list, it creates a new list where each member is an instance of ILeader
. Which means that ChangeList could add a Group
to the list, meaning you couldn't convert it back to a List<User>
.
If ChangeList
doesn't add any members to the list you can just convert it back:
var leaderList = userList.Cast<ILeader>().ToList();
ChangeList(leaderList);
userList = leaderList.Cast<User>().ToList();
If ChangeList
adds any items other than User
s then the conversion will fail. Your best choice is to take only the User
s from the result:
var leaderList = userList.Cast<ILeader>().ToList();
ChangeList(leaderList);
userList = leaderList.OfType<User>().ToList(); // will ignore anything that's not a `User`
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With