Vous recherchez de façon générique pour mettre en œuvre la fonction dans la classe de base
-
29-09-2019 - |
Question
Je suis en train de faire une mise en oeuvre simple du motif Spécification dans ma couche de domaine.
Si j'ai une classe statique complète des spécifications comme ceci:
public static class FooSpecifications
{
public static Func<Foo, bool> IsSuperhuman
{
get
{
return foo => foo.CanShootLasersOutOfItsEyes && foo.CanFly;
}
}
}
Alors je peux faire des choses merveilleuses comme ceci:
IEnumerable<Foo> foos = GetAllMyFoos();
var superFoos = foos.Where(FooSpecifications.IsSuperhuman);
Je peux aussi ajouter bool méthode Foo pour déterminer si une instance particulière répond à un cahier des charges:
public bool Meets(Func<Foo, bool> specification)
{
return specification.Invoke(this);
}
Étant donné que Foo, comme toutes mes entités de domaine, étend DomainObject, est-il un moyen que je peux mettre une implémentation générique de Meets () dans le DomainObject pour me sauver la mise en œuvre rencontre () séparément dans chaque entité?
La solution
Quelque chose comme ça ...
public abstract class DomainObj<T> // T - derived type
where T : DomainObj<T>
{
public bool Meets(Func<T, bool> specification)
{
return specification.Invoke((T) this);
}
}
public class Foo : DomainObj<Foo> {}
public class Bar : DomainObj<Bar> {}
Func<Foo, bool> foospec = x => true;
Func<Bar, bool> barspec = x => true;
var foo = new Foo();
var bar = new Bar();
foo.Meets(foospec);
foo.Meets(barspec); // won't compile because of mismatched types of spec and object instance
EDIT
Peut-être qu'il sera préférable de traduire rencontre méthode pour l'extension. Cela supprime le besoin dans le paramètre de type.
public abstract class DomainObj
{
}
public static class DomainObjExtensions
{
public static bool Meets<T>(this T obj, Func<T, bool> f)
where T : DomainObj
{
return f(obj);
}
}
public class Foo : DomainObj {}
public class Bar : DomainObj {}
Func<Foo, bool> foospec = x => true;
Func<Bar, bool> barspec = x => true;
var foo = new Foo();
var bar = new Bar();
foo.Meets(foospec);
foo.Meets(barspec); // error