首页 文章

为什么非泛型派生类型必须为泛型基类C#指定类型参数

提问于
浏览
3

在Andrew Tolson的Pro C#中,作者说当非泛型类扩展泛型基类时,派生类必须指定类型参数 .

// Assume you have created a custom
// generic list class.
public class MyList<T>
{
  private List<T> listOfData = new List<T>();
}
// Non-generic classes must specify the type
// parameter when deriving from a
// generic base class.
public class MyStringList : MyList<string>
{}

我不明白为什么这是必要的?

5 回答

  • 7

    反过来想想它 . 如果没有为基类型指定type参数, MyList<T> 应该使用哪种类型?它仍然是未定义的 .

    您可以创建从另一个泛型类型继承的泛型类型,然后您不必指定超类型的类型参数;你的客户可以做到 .

  • 5

    好吧,非泛型类没有类型参数,泛型类有一个或多个类型参数 .

    如果从泛型类继承该类,而不指定type参数,则仍然具有泛型类,即

    public class MyList<T> : List<T> {} //MyList is still generic
    

    public class MyList : List<T> {} //invalid declaration, what is T ?
    

    所以

    public class MyStringList : List<string> {} //specified with string
    

    或者,更一般的

    public class MyArrayList : List<object> {} //specified with object
    

    一个更罗嗦的解释,主要是因为我喜欢使用“arity”这个词 .

    CLR中的类可以具有零或更多的arity,这意味着它们可以指定零个或多个类型参数 . 但是,CLR无法实例化具有非零arity的类,因此为了做任何有用的事情,必须将类的arity降低到零 .

    这意味着,虽然我们可以部分指定类,如:

    public class IntKeyDictionary<TValue> : Dictionary<int, TValue>
    

    减少arity,甚至声明类似的类

    public class ListAndAHalf<TOne, TTwo> : List<TOne>
    

    增加了arity,故事必须以一个arity为0的类结束,如 List<string>Dictionary<int, double> 等...

  • 4

    因为否则它's not a usable type because the CLR still doesn'知道 T 使用哪种类型 .

    List<T>open 类型,因为 T 尚未替换为可实例化类型 . 而且您无法创建开放类型的实例 . 您只能在 closed 时创建类型的实例,即当其所有类型参数(包括封闭类型和基类型)已被可实例化类型替换时 .

    如果您能够声明 class MyTList : MyList<T> { } ,那么您永远无法为 T 指定类型,因为 MyTList 不再包含该类型参数,因此您永远无法实例化 MyTList . 这不是一个非常有用的课程 .

  • 2

    如果您没有指定类型,那么唯一的另一个选择是使派生类也是通用的 .

    public class MyDerivedList<T> : MyList<T>
    {
    }
    
  • 2

    如果不是怎么办?

    您的 MyStringList 将是通用的(因为 T 不会有硬编码类型),但是根据定义,它不是构建非泛型类 .

相关问题