2010-08-19 71 views
3

我想在我的領域層做一個簡單的規範模式實現。尋找通用的方法來實現基類中的功能

如果我有一個靜態類全規格如下:

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); 

我還可以添加布爾方法來富,以確定是否一個特定的例子符合一個規範:

public bool Meets(Func<Foo, bool> specification) 
{ 
    return specification.Invoke(this); 
} 

鑑於Foo,就像我所有的域entiti es,擴展DomainObject,有沒有辦法將Meets()的通用實現放入DomainObject中,以便在每個實體中分別實現Meets()?

+0

提示:您可以使用Predicate 而不是Func 。 – 2010-08-19 10:49:51

+2

@Paul:你可以,但是更新版本的框架,特別是LINQ的趨勢是使用'Func '而不是'Predicate '。 – LukeH 2010-08-19 10:54:56

+0

@LukeH:有趣的,不知道這個(顯然)謝謝。 – 2010-08-19 12:41:53

回答

0

事情是這樣的......

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 
+0

派生類聲明之後的大括號是什麼?當我把它們放入時,我開始變得'命名空間不能包含成員的編譯器錯誤。 – David 2010-08-19 11:08:24

+0

無論哪種方式,在派生類中,編譯器不能識別DomainObject類型,即使它們位於相同的名稱空間中。 – David 2010-08-19 11:09:46

+0

我的不好:我粘貼了一些你的代碼,但沒有注意到你正在使用DomainObj而不是DomainObject。 – David 2010-08-19 11:13:32

相關問題