سؤال

أحاول القيام بتنفيذ بسيط لنمط المواصفات في طبقة النطاق الخاصة بي.

إذا كان لدي فئة ثابتة مليئة بالمواصفات مثل هذا:

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 ، هل هناك طريقة يمكنني من خلالها وضع تنفيذ عام لل Meets () في DomainObject لإنقاذ لي تنفيذ Meets () بشكل منفصل في كل كيان؟

هل كانت مفيدة؟

المحلول

شيء من هذا القبيل...

    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