Ищете общий способ реализации функции в базовом классе
-
29-09-2019 - |
Вопрос
Я пытаюсь сделать простую реализацию шаблона спецификации в моем доменном слое.
Если у меня есть статический класс, полный спецификаций, таких как это:
public static class FooSpecifications
{
public static Func<Foo, bool> IsSuperhuman
{
get
{
return foo => foo.CanShootLasersOutOfItsEyes && foo.CanFly;
}
}
}
Тогда я могу сделать изумительные вещи, такие как это:
IEnumerable<Foo> foos = GetAllMyFoos();
var superFoos = foos.Where(FooSpecifications.IsSuperhuman);
Я также могу добавить метод BOOL для Foo, чтобы определить, соответствует ли определенный экземпляр спецификации:
public bool Meets(Func<Foo, bool> specification)
{
return specification.Invoke(this);
}
Учитывая, что Foo, как и все мои доменные субъекты, расширяют DomainObject, есть ли способ, которым я могу поставить общую реализацию соответствующих () в DomainObject, чтобы сэкономить меня реализует () отдельно в каждой сущности?
Решение
Что-то вроде этого...
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
РЕДАКТИРОВАТЬ
Может быть, лучше перевести метод встречи на расширение. Это удалит потребность в типе параметр.
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
Не связан с StackOverflow