We inherited a project that is a wrapper around a section of the core business model.
There is one method that takes a generic type, finds elements matching that type from a member, and then returns a list of that type.
public List<T> GetFoos<T>() { List<IFoo> matches = Foos.FindAll( f => f.GetType() == typeof(T) ); List<T> resultList = new List<T>(); foreach (var match in matches) { resultList.Add((T)obj); } }
Foos can hold the same object in different classes in the inheritance hierarchy to summarize the results differently for different user interface presentations. There are 20+ different types of descendants that GetFoos can return.
Existing code basically has a large switch statement copied and pasted into the whole code. The code in each section calls GetFoos with the appropriate type.
We are currently reorganizing this into one consolidated area, but as we do this, we are considering other ways of working with this method.
One thought was to use reflection to pass in a type, and this worked fine until we realized that Invoke returned the object and that it needed to be somehow passed to List <T>.
Another was to simply use the switch statement before 4.0, and then use the parameters of the dynamic language.
We welcome any alternative thoughts on how we can work with this method. I left the code pretty concise, but if you want to know any additional data, just ask.
Update
The switch statement originally used strings, and the first pass moved it to Presenter with something like this: (Refactoring was not performed on the switch where the data was).
// called on an event handler in FooPresenter // view is the interface for the ASPX page injected into FooPresenter constructor // wrapper is the instance of the model wrapper that has the GetFoos method // selectedFooName is the value of a DropDownList in the Page // letting the user say how they want to see the animals // its either one big group (Animal) // or individual types (Tiger, Lion) private void LoadFoos(string selectedFooName) { switch (selectedFooName) { case "Animal": // abstract base class for all other types this.view.SetData(this.wrapper.GetFoos<Animal>(); case "Lion": this.view.SetData(this.wrapper.GetFoos<Lion>(); break; case "Tiger": this.view.SetData(this.wrapper.GetFoos<Tiger>(); break; case "Bear": this.view.SetData(this.wrapper.GetFoos<Bear>(); break; } }
View implementation (codebehind for ASPX page)
public void SetData<T>(List<T> data) {
Our first pass was to at least use Type in a switch statement or add an enumeration.
I played using the strategy template, but I had to stop when I got to the factory loading, returning the list again, and realized that I did not have it.