J'ai une douzaine de méthodes dans mon projet (C # 2.0) qui ressemblent à ceci: ... mais pour différentes classes "entités". (D'accord, pas tout à fait ce trivial, j'ai simplifié le code ici.) P> Il ressemble à un bon candidat pour les génériques et je suis venu avec ceci: p> internal bool ValidateEntity<T>(DataRow row) where T : EntityBase
{
return (new T(row)).Validate();
}
4 Réponses :
Un moyen simple est de fournir une fonction d'usine: et appelez avec: p> Mind You, à ce stade plus compliqué que simplement appeler p> en premier lieu ... p> Ce n'est pas vraiment clair ce que vous essayez d'atteindre dans votre contexte réel, Mais ce type d'approche usine / fournisseur peut certainement être utile à d'autres moments. Notez que appeler un délégué d'usine peut également être considérablement em> plus rapide que d'utiliser Edit: Pour .NET 2.0 Compatibilité Vous devez déclarer le délégué vous-même, mais c'est facile: P> nouveau t () code> avec une contrainte, Comme je me suis blogué il y a quelque temps . Nérormiant dans de nombreux cas, mais la peine d'être connue. P> bool valid = ValidateEntity(row, delegate(DataRow x) { return new Foo(x); });
Je ne pense pas qu'il y ait un fonctionnement en 2.0.
@PeterTrevor: Oups, n'avait pas remarqué l'exigence .NET 2.0 - mais vous pouvez facilement définir vos propres délégués. Va éditer pour donner un exemple de cela.
@Shibumi définitivement, je suis surpris que l'OP a choisi ma réponse, mais je suppose qu'il voulait juste quelque chose qui a équipé sa méthode actuelle Signature
Merci tout le monde. @Jon: Pour ce cas, c'est vraiment C # 2 (vs2005) ... pas mon choix. Mais j'ai déposé toutes ces suggestions pour une utilisation ultérieure, ce type de problème est tenu de conclure à nouveau sur un projet différent (celui qui utilise VS2010).
@Petertrevor: Mais comme je l'ai dit dans mon édition, vous n'avez pas besoin de C # 3 pour que cela fonctionne. Il fait qu'il a Néater d'utiliser des expressions Lambda, mais c'est tout. Je me demande encore si cela est nécessaire du tout si ...
Un exemple de la solution de méthode d'usine @johnsaunders:
Encore une autre manière pourrait être d'impliquer une réflexion au prix de la vérification du temps de compilation et de la diminution des performances:
internal bool ValidateEntity<T>(DataRow row)
{
object entity = Activator.CreateInstance(typeof(T), new object[] { row });
MethodInfo validate = typeof(T).GetMethod("Validate");
return (bool) validate.Invoke(entity, new object[]);
}
Si validez () lancera une exception, il sera enveloppé dans la cibleVocationException, je ne pense pas que ce bien. Le casting à l'entitébase semble être beaucoup plus préférable.
Vous pouvez mettre en cache que MethodInfo dans une variable statique (car il est générique, il serait par type fermé). Maintenant, vous supprimez la nécessité de le refléter pour chaque appel.
@MIKEbrown Oui, vous pouvez mais vous devrez maintenir un type à la méthodyinfo dictionnaire (les classes pourraient ne pas avoir d'ancêtres communs)
Ah oui je vois. Ceci est une fonction générique. Je pensais que cela pourrait être une classe d'assistance de validation générique. Si la classe a été fermée sur T, vous pouvez utiliser la variable statique. Mais vous avez raison, cela ne fonctionnera pas pour une seule méthode générique.
Vous pouvez faire quelque chose comme ceci:
Je n'ai pas le temps pour un exemple maintenant, mais vous pouvez créer une méthode d'usine générique pouvant être passée à la ligne.
Pourquoi passez-vous autour des datarses au lieu de vos entités? Les entités ne devraient-elles pas être validées bien avant leur traitement comme des datarses?
Ils n'étaient pas vraiment datarow, ils étaient des objets de type datarow que j'ai simplifié 'pour ce post. Je ne voulais pas me faire détecter l'explication du cadre imposé que je dois faire face.