The other day I was working with some generic lists of some custom classes.
All of these classes inherited from a common base class.
I wanted to write a method where I could pass any of my generic lists to this method and iterate over the list and execute some other code.
I thought this was a perfect example for passing a generic type into my method. I tried everything I know and could not get this to work.
I posted a question on the MSDN forums about my problem and John Grove pointed me at this article.
So it turns out what I was wanting was a Covariant Generic List.
I pretty much followed what was outlined in the article, but I will document here what I exactly did, namely because I had a hard time finding the solution to this problem.
This starts off by defining a interface for our base class.
public interface IClassInterface
{
string Property1 { get; set; }
string Property2 { get; set; }
}
Then we have to define our base class, plus any class that
inherits from it.
public class ClassA : IClassInterface
{
public ClassA() {}
public ClassA(ClassA objectA)
{
this.Property1 = objectA.Property1;
this.Property2 = objectA.Property2;
}
public ClassA(string property1, string property2)
{
this.Property1 = property1;
this.Property2 = property2;
}
public string Property1
{
get; set;
}
public string Property2
{
get; set;
}
}
public class ClassB : ClassA
{
public ClassB() {}
public ClassB(ClassA objectA, string property3, string property4)
: base(objectA)
{
this.Property3 = property3;
this.Property4 = property4;
}
public string Property3
{
get; set;
}
public string Property4
{
get; set;
}
}
Next we define a class that a returns enumerable generic list.
public class EnumerableGeneric<TClass, TInterface>
: IEnumerable<TInterface> where TClass : TInterface
{
private IList<TClass> list;
public EnumerableGeneric(IList<TClass> list)
{
this.list = list;
}
public IEnumerator<TInterface> GetEnumerator()
{
foreach (TClass item in list)
{
yield return item;
}
}
IEnumerator IEnumerable.GetEnumerator()
{
return this.GetEnumerator();
}
}
Next we define our method that we are going to use to perform
some operation on each of the lists.
private void MyMethod(IEnumerable<IClassInterface> genericList)
{
foreach (IClassInterface classVariable in genericList)
{
// Other code goes here.
}
}
And finally we create our lists, populate some data and call our method.
List<ClassA> caInstance = new List<ClassA>();
caInstance.Add(new ClassA("A", "B"));
caInstance.Add(new ClassA("C", "D"));
List<ClassB> cbInstance = new List<ClassB>();
cbInstance.Add(new ClassB(new ClassA("E", "F"), "G", "H"));
cbInstance.Add(new ClassB(new ClassA("I", "J"), "K", "L"));
MyMethod(new EnumerableGeneric<ClassA, IClassInterface>(caInstance));
MyMethod(new EnumerableGeneric<ClassB, IClassInterface>(cbInstance));
I appreciate John Grove for taking the time on the MSDN forums to answer my question and also to Stefan Delmarco for posting the original article.
Hope this helps somebody else, I know it helped me.