Coming from Java or Python I am used to making such constructs and normally it “just works”. Been discovering C# lately and, other than a few frustrations, find it quite pleasant to work with.
One such frustration is how much I have to hold it’s hands through polymorphism constructs (override, virtual, etc).
Here is one such case I have not yet found how to “just make work”.
class Polymorphism
{
public interface IPerson
{
String Name { get; set; }
}
public class Doctor : IPerson
{
public String Name { get; set; }
}
public class DoctorGroup
{
public IEnumerable<IPerson> Members
{
get
{
return DoctorMembers;
}
}
public List<Doctor> DoctorMembers { get; set; }
public DoctorGroup()
{
DoctorMembers = new List<Doctor>();
}
}
}
Here the DoctorMembers are IPersons, thus I should be able to just return a list of doctors when asked for an IEnumerable of IPerson.
public IEnumerable<IPerson> Members
{
get
{
return DoctorMembers;
}
}
Yet… the compiler complains… why? What am I missing? Semantically there is nothing wrong with this, most OOP languages I have worked with thus far can digest this without syntactic Pepto-Bismol. Am I missing a keyword to make it obvious to the compiler?
The obvious shortcut here is to LINQ convert all the doctors to IPerson but I fail to see why this is necessary or even desirable.
Anybody can light my lantern?
This code does compile with C# 4 targeting .NET 4, but wouldn’t have compiled in C# 3, which didn’t have generic variance.
Basically you want an implicit conversion from
IEnumerable<Doctor>toIEnumerable<IPerson>. That’s safe, because you can only get values “out” of anIEnumerable<T>… which is why in .NET 4, it’s declared asIEnumerable<out T>.Read more on generic variance for details, and remember that this is only available in C# 4 and upwards.
(If you have to use C# 3 or .NET 3.5, you can use the solution shown by CSharpie… but ideally, upgrade to a more recent version 🙂