抽象类中的泛型类型和方法

时间:2014-12-08 02:07:18

标签: c# generics abstract-class

我将从代码开始,然后是问题。但它是一个比实际代码更简单的版本:

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的后代,因此它可以在编译时检查参数类型是否正常,而不必在运行时检查类型

1 个答案:

答案 0 :(得分:2)

您可以使用SettingsItem关键字为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);
}