2014-12-08 100 views
0

我要從代碼開始,然後是問題。這是一個更簡單的版本比實際代碼,雖然:抽象類中的泛型類型和方法

class SettingsItem<T> 
{ 
} 

class SettingsItemWhatever: SettingsItem<string> 
{ 
} 

現在的問題是,我想有一類像,讓我們說:

class abstract SettingsContainer 
{ 
} 

將存儲類型SettingsItem的對象它是後代,無論T是哪一個,都會有一些Set和Get方法。它也必須是一個抽象類,所以工作將在其後代完成,而這隻會定義那些必須實現的方法。

嘗試編碼此類方法時出現問題。到目前爲止,儘管我試過,導致更不方便了一些其他的方法,我發現最好的是這樣的:

class abstract SettingsContainer 
{ 
    public abstract Set<T> (T item); 
    public abstract Get<T> (string key); 
} 

這種方法的問題是,你可以調用你想要的任何參數的功能,並作爲儘管它們是抽象的,但它們不能對參數類型進行任何測試,因爲T不得不是任何SettingsContainer派生類中的SettingsItem或其後代。

除此之外,我認爲應該有一種方法告訴編譯器參數必須是SettingsItem的後代,因此它可以在編譯時檢查參數類型是否正確,而不必在運行時檢查類型代替。

回答

2

您可以SettingsItem創建一個非泛型基類和specifiy它的約束,使用where關鍵字:

abstract class SettingsItem 
{ 
    public string Key {get;} 
} 

class SettingsItem<T> : SettingsItem { 

    public T Value {get;} 
} 

abstract class SettingsContainer { 
    public abstract void Set<T>(T item) where T : SettingsItem; 
    public abstract T Get<T> (string key) where T : SettingsItem; 
} 

或者,你可以添加其他類型的參數,包括在約束SettingsItem<T>

abstract class SettingsContainer { 
    public abstract void Set<T,U>(T item) where T : SettingsItem<U>; 
    public abstract T Get<T, U> (string key) where T : SettingsItem<U>; 
} 

除非你實際使用的情況下所需要的類型是一個參數,你可能也只是將其包含在方法簽名:

abstract class SettingsContainer { 
    public abstract void Set<T>(SettingsItem<T> item); 
    public abstract SettingsItem<T> Get<T> (string key); 
}