Nous avons hérité d'un projet qui entoure une section du modèle métier principal.Suggestions pour utiliser cette méthode générique héritée
Une méthode prend un élément générique et trouve des éléments correspondant à ce type dans un membre, puis renvoie une liste de ce 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 peut contenir le même objet jeté dans différentes classes dans la hiérarchie d'héritage aux totaux agrégés différemment selon les présentations de l'interface utilisateur. Il y a 20 types différents de descendants qui peuvent être retournés par GetFoos.
Le code existant a essentiellement une grande instruction de commutateur copiée et collée dans le code. Le code dans chaque section appelle GetFoos avec son type correspondant.
Nous sommes en train de refactoriser cela dans une zone consolidée, mais comme nous le faisons, nous examinons d'autres façons de travailler avec cette méthode. Une pensée était d'utiliser la réflexion pour passer dans le type, et cela fonctionnait bien jusqu'à ce que nous nous rendions compte que l'Invoke renvoyait un objet, et qu'il devait être jeté d'une manière ou d'une autre à la liste <T>.
Un autre était d'utiliser simplement l'instruction switch jusqu'à la version 4.0, puis d'utiliser les options de langage dynamique.
Nous nous réjouissons de toute autre réflexion sur la façon dont nous pouvons travailler avec cette méthode. J'ai laissé le code assez court, mais si vous souhaitez connaître d'autres détails, n'hésitez pas à demander.
Mise à jour
L'instruction switch a été à l'origine au moyen de chaînes et le premier passage se déplaçait dans un présentateur avec quelque chose comme ceci: (refactorisation fait sur le commutateur, à l'endroit où les données sont allés).
// called on an event handler in FooPresenter
// view is the interface for the ASPX page injected into FooPresenter's 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;
}
}
La mise en œuvre de vue (codebehind pour une page ASPX)
public void SetData<T>(List<T> data)
{
// there is a multiview on the page that contains user controls with
// grid layouts for the different types
// there is a control for the common type of "Animal"
// and other controls for Tiger, Bear, etc
// the controls contain a 3rd party grid of pain
// and the grids' binding event handlers cast the data item
// for the row and do some stuff with it specific to that type
}
Notre premier passage allait être au moins en utilisant le type dans l'instruction switch, ou l'ajout d'un ENUM.
J'ai joué avec l'utilisation du Pattern Stratégie mais j'ai dû arrêter quand je suis arrivé à l'usine de chargement en retournant la Liste et en réalisant que je n'avais pas le type.
Pouvez-vous nous montrer votre déclaration de commutateur? Que fait-il réellement? –