I have a helper class that does a simple but repetitive process on a List of entities. For simplicity, it’s like this…
public static List<MyType> DoSomethingSimple(List<MyType> myTypes) {
return myTypes.Where(myType => myType.SomeProperty.Equals(2)).ToList();
}
I now need to add support for another type, but everything is identical… how do I avoid an increasing list of overloaded methods like this:
public static List<MyType> DoSomethingSimple(List<MyType> myTypes) {
return myTypes.Where(myType => myType.SomeProperty.Equals(2)).ToList();
}
public static List<MyOtherType> DoSomethingSimple(List<MyOtherType> myOtherTypes) {
return myOtherTypes.Where(myOtherType => myOtherType.SomeProperty.Equals(2)).ToList();
}
… and so on.
Here’s two ways:
Method 1:
Method 2:
Now, if you try to make the method use the interface directly, like this:
Then that would work if you have a
List<ICommon>when you call it, but won’t work if you have aList<MyType>. In C# 4.0 this can be done if we change the method slightly:Note that I changed to using an
IEnumerable<ICommon>instead. The concept here is called Co- and contra-variance, and beyond that I’m not going to say much about it. Search Stack Overflow for more information on the subject.Tip: I would change the input parameter to be
IEnumerable<T>regardless, since this would make your method usable in more instances, you could have different types of collections, arrays, etc. and as long as they contain the right type, they can be passed to the method. By limiting yourself toList<T>you force the user of your code to convert to a list in some cases. My guidelines are to be as unspecific as possible in input parameters, and as specific as possible in output parameters.