2009-12-03 33 views
2

我已經定義了以下泛型類使用泛型和支持子類跟蹤實例

public class ManagedClass<T> where T : ManagedClass<T> 
{ 
    static ManagedClass() 
    { 
     Manager = new ObjectManager<T>(); 
    } 
    public static ObjectManager<T> Manager { get; protected set; } 

    public ManagedClass() 
    { 
     Manager.Add((T)this); 
    } 
} 

這個想法是我可以像這樣使用它:

class Product : ManagedClass<Product> {} 

現在我可以對第7個產品做點什麼:

Product.Manager.GetById(7).DoSomething(); 

問題來自如果我嘗試使用派生類:

class ExtendedProduct : Product {} 

現在ExtendedProduct.Manager有一個'Products'列表,如果我想使用我添加的新功能ExtendedProduct(DoSomethingElse),我必須像這樣拋出我得到的對象:

((ExtendedProduct)ExtendedProduct.Manager.GetById(7)).DoSomethingElse(); 

這有點難看,而使用泛型的全部意義在於避免投射。我想我可以在派生類中添加一個靜態構造函數來設置Manager = new ObjectManager()並在派生類構造函數中添加一個新的Manager.addObject(this),但似乎應該有更好的方法來執行此操作仿製藥。有什麼建議?

回答

1

問題是ExtendedProduct.ManagerProduct.Manager是同一回事;經理對象不能根據訪問的位置而採取不同的行爲。

一對夫婦的可能性我能想到的:

  1. 隱藏GetById方法裏面的類型轉換通過使通用的:每個子類 Product.Manager.GetById<ExtendedProduct>(7).DoSomethingElse();

  2. 使用一個ObjectManager例如,如果私自將它們連接需要

選項1讓我想起NHib ernate的ICriteria接口。它與類型轉換實際上是一樣的,但意外中斷有點困難。

1

真的是你碰到的是泛型的弱點。一旦你的課程已經解決了它用於泛型的類型,你在某種程度上受到限制。

通常情況下,我會說依賴注入將是一個救世主在這裏,但因爲有問題的方法是static,這混淆了水域。

我想說的最好的事情是要有的ObjectManager類爲你做的工作:

static public class ObjectManager<T> 
{ 
    ... the code that already exists in ObjectManager ... 

    static public U GetById<U>(long id) 
    { 
     object obj = GetById(id); 
     if (obj is U) 
      return (U)obj; 
     return default(U); 
    } 
} 

然後,在你的代碼:

ExtendedProduct.Manager.GetById<ExtendedProduct>(7).DoSomethingElse(); 

這不是真的萬噸,比更優雅鑄造,但可能是使用泛型的唯一解決方案之一。

相關問題