2010-11-27 84 views
4

我猜標題並沒有說太多,所以這裏是解釋。來自子類的C#泛型類型參數,可能嗎?

我有一個父類,我想要持有一個事件Action,其中T是任何子類繼承它的類型。

例如這樣的事情:

abstract class ActiveRecord 
{ 
    protected event Action<T> NewItem; 
} 

class UserRecord : ActiveRecord 
{ 
    public UserRecord() 
    { 
    NewItem += OnNewItem; // NewItem would in this case be Action<UserRecord> 
    } 

    private void OnNewItem(UserRecord obj) 
    { 
    // Flush cache of all users, since there's a new user in the DB. 
    } 
} 

所以問題是,是上述可能的,我會在父類中使用T?

請注意,我不希望我的父類的泛型參數,因爲這真的看起來很愚蠢,從而妨礙了可讀性。

class UserRecord : ActiveRecord<UserRecord> 

我正在研究基於ORM的繼承,以防萬一您想知道它的用途。每當ORM將數據插入數據庫時​​,都會引發NewItem事件。

編輯:嘗試澄清一點更好,正確命名的類。

ActiveRecord類駐留在一個單獨的程序集中,UserRecord駐留在我正在處理的Web項目中。 (注意:我是這兩個部分的開發人員,但是它是兩個單獨的項目)

我希望能夠在成功插入行,刪除行等時引發事件。這些事件應該將有關記錄作爲參數傳遞給事件處理程序,因此需要Action。

但是,因爲我在基類(ActiveRecord)中聲明瞭這些事件,我需要一些方法將CHILD類型傳遞給事件處理程序,以獲取強類型對象。

當然可以去動作,然後做一個類型轉換在我的實現,但真的不會是非常好的:-(

希望這清除了問題了一點,否則請諮詢: - )

編輯2:只是想讓你知道反射,動態方法或類似的東西是一個選項,如果這會有所幫助。但是我懷疑它:-(

+4

這兒有什麼東西出錯 - 孩子是你的模型和父母的物品是容器嗎?或者這是另一種方式?你能解釋一些嗎? – 2010-11-27 09:53:15

回答

0

其實我覺得我只是找到了一個更好的方法:

abstract class ActiveRecord 
{ 
    protected virtual void OnNewItem() {} 
} 

class UserRecord : ActiveRecord 
{ 

    protected override void OnNewItem() 
    { 
    // Still got the UserRecord object, now it's just "this" 
    } 
} 

這似乎更清潔的我,所以我將使用的是代替。

6

此特定情形,我不會真的建議,但你可以使用curiously recurring template pattern的C#版本:

class Parent<T> where T : Parent<T> 
{ 
    protected event Action<T> NewItem; 
} 


class Child : Parent<Child> 
{ 
    public Child() 
    { 
     NewItem += OnNewItem; 
    } 

    private void OnNewItem(Child obj) 
    { 
     // Do something 
    } 
} 

在實踐中,這將是相當困難的。使用合理;必須有一個更好的解決方案,以整體設計,在所有誠實

+0

我同意這樣做會很難明智地使用,並且由於其他人可能會最終使用該庫,這是我的首要任務。 (還是)感謝你的建議。 – Steffen 2010-11-27 16:07:57

+0

這似乎是最好的方法。 – Steffen 2010-11-28 07:33:14

0

試試這個:

abstract class Parent<T> 
{ 
    public event Action<T> NewItem; 
} 

class Child : Parent<Child> 
{ 
    public Child() 
    { 
     NewItem += OnNewItem; 
    } 

    private void OnNewItem(Child obj) 
    { 
     // Do something 
    } 
} 

如果你不能讓Parentabstract,則可以在ParentChild之間添加一個抽象轉換類。

class Parent<T> 
{  
    public event Action<T> NewItem; 
} 

abstract class Transition<T> : Parent<T> { } 

class Child : Transition<Child> 
{ 
    public Child() 
    { 
     NewItem += OnNewItem; 
    } 
    private void OnNewItem(Child obj) 
    { 
     // Do something 
    } 
}