Ищете общий способ реализации функции в базовом классе

StackOverflow https://stackoverflow.com/questions/3520910

Вопрос

Я пытаюсь сделать простую реализацию шаблона спецификации в моем доменном слое.

Если у меня есть статический класс, полный спецификаций, таких как это:

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
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top