You may have just simplified your script, but the smelly part of your function is casting to SomeObject. Could you just work with the interfaces and (if necessary) bring the result to the call site? You can use your Type1 and Type2 common interface, where id1 and id2 will be displayed as id, for example (or decorate them if you do not control Type1 and Type2)
those.
public static IMyObject GetTheObject(List<IMyObject> theList, int id) { var ret = (from o in theList where o.id==id select o).FirstOrDefault(); return ret; }
For example, if you have:
public interface IMyObject {int id {get;}} public class Foo : IMyObject {public int id {get; set;}} public class Bar : IMyObject {public int id {get; set;}}
You can do:
var l1 = new List<IMyObject>(){new Foo(){id=1}, new Foo(){id=2}}; var l2 = new List<IMyObject>(){new Bar(){id=1}, new Bar(){id=2}}; var obj1 = Test.GetTheObject(l1, 1); var obj2 = Test.GetTheObject(l2, 2);
And discard objects after calling the function if you need to.
EDIT: if you are stuck with specific objects and castes, the best refactoring I could come up with is:
public static SomeObject GetTheObject(IMyObject genericObject) { Type t = genericObject.GetType(); Func<SomeObject, bool> WhereClause = null; IEnumerable<SomeObject> objs = null; // IEnumerable<T> is covariant, // so we can assign it both an IEnumerable<object1> // and an IEnumerable<object2> (provided object1 and 2 are // subclasses of SomeObject) switch(t.Name) { case "Type1": WhereClause = o => ((Object1)o).object1id == genericObject.id; objs = object1s; break; case "Type2": WhereClause = o => ((Object2)o).object2id == genericObject.id; objs = object2s; break; } var ob = objs .Where(WhereClause) .FirstOrDefault(); return (SomeObject)ob; }
source share