Cerchi modo generico per implementare la funzione di classe di base
-
29-09-2019 - |
Domanda
Sto cercando di fare una semplice implementazione del pattern specifica nel mio livello di dominio.
Se ho una classe statica completa di specifiche in questo modo:
public static class FooSpecifications
{
public static Func<Foo, bool> IsSuperhuman
{
get
{
return foo => foo.CanShootLasersOutOfItsEyes && foo.CanFly;
}
}
}
Allora posso fare cose meravigliose in questo modo:
IEnumerable<Foo> foos = GetAllMyFoos();
var superFoos = foos.Where(FooSpecifications.IsSuperhuman);
I può anche aggiungere bool metodo per Foo per determinare se una particolare istanza incontra una specifica:
public bool Meets(Func<Foo, bool> specification)
{
return specification.Invoke(this);
}
Dato che Foo, come tutti i miei entità del dominio, si estende DomainObject, c'è un modo posso mettere un'implementazione generica di Meets () nella DomainObject per salvarmi attuazione Meets () separatamente in ogni entità?
Soluzione
qualcosa di simile ...
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
Modifica
Forse sarà meglio tradurre il metodo Incontra per estensione. Questo eliminerà necessità nel parametro tipo.
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
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow