Expression > - Comment gérer Ambigu Méthode Signatures?
-
01-10-2019 - |
Question
J'ai un contrat d'interface qui ressemble à ceci:
ICollection<FooBar> FindByPredicate(Expression<Func<FooBar,bool>> predicate);
ICollection<Foo> FindByPredicate(Expression<Func<Foo,bool>> predicate);
ICollection<Bar> FindByPredicate(Expression<Func<Bar,bool>> predicate);
Foo et Bar sont des classes concrètes qui héritent de la classe abstraite FooBar.
Maintenant, im avoir des problèmes en essayant d'invoquer ces méthodes:
var foo = myService.FindByPredicate(f => f.UserId == 1);
Il devient des erreurs « d'invocation ambiguë », quel type de sens de marques, parce que la propriété « UserId » existe sur le type abstrait « foobar » (et existe donc sur Foo et Bar ainsi).
Alors, comment puis-je surmonter cela?
Je aime l'apparence de mon interface (surcharge des méthodes sous-jacentes) à partir d'un point de vue IntelliSense du code d'appel, il n'y a qu'un seul nom de la méthode.
Pourquoi dois-je mon interface comme ça? Eh bien, certains scénarios Je voudrais revenir seulement « Foo » ou « Bar », d'autres fois je besoin d'un sac mélangé, je dois donc retourner le type abstrait - du sens
Quoi qu'il en soit, sur la question évidente - est-il un moyen de contourner cela? (Autre que de renommer mes méthodes d'interface)? (Et compromettre ainsi la simplicité)
La solution
Vous pouvez déclarer la méthode pour être générique, et vous avez besoin qu'une seule méthode:
public interface IFooBarService
{
ICollection<T> FindByPredicate<T>(Expression<Func<T, bool>> predicate)
where T : FooBar;
}
et alors vous pouvez l'appeler comme ceci:
var foo = myService.FindByPredicate<Foo>(f => f.UserId == 1);
Autres conseils
Vous pouvez déclarer le type de f
dans le lambda plutôt que de le laisser déduire. De cette façon, une seule surcharge sera applicable.
var foo = myService.FindByPredicate((Foo f) => f.UserId == 1);
var bar = myService.FindByPredicate((Bar f) => f.UserId == 1);
var foobar = myService.FindByPredicate((FooBar f) => f.UserId == 1);