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

C# 为什么非泛型派生类型必须为泛型基类C指定类型参数#,c#,.net,generics,C#,.net,Generics,在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 //

在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>
{}
//假设您已经创建了自定义
//泛型列表类。
公共类MyList
{
私有列表listOfData=新列表();
}
//非泛型类必须指定类型
//当从
//泛型基类。
公共类MyStringList:MyList
{}

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

嗯,非泛型类没有类型参数,泛型类有一个或多个类型参数

// 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>
{}
如果从泛型类继承该类,而不指定类型参数,则仍然有一个泛型类,即

public class MyList<T> : List<T> {} //MyList is still generic
public类MyList:List{}//MyList仍然是泛型的
但是

public类MyList:List{}//声明无效,T是什么?
所以

public类MyStringList:List{}//用字符串指定
或者,更一般地说

public class MyArrayList : List<object> {} //specified with object
公共类MyArrayList:使用对象指定的列表{}//

一个更冗长的解释,主要是因为我喜欢用“”这个词

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

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

public class IntKeyDictionary<TValue> : Dictionary<int, TValue>
公共类IntKeyDictionary:字典
这会降低算术性,甚至会像

public class ListAndAHalf<TOne, TTwo> : List<TOne>
public类列表andhalf:List

这增加了算术性,故事必须以一个算术性为0的类结束,比如
List
Dictionary
等等。

因为否则它是不可用的类型,因为CLR仍然不知道使用
t
的类型

List
是一种open类型,因为
T
尚未被可实例化类型替换。并且不能创建开放类型的实例。只有当类型处于关闭状态时,即当其所有类型参数(包括封闭类型和基类型)都被可实例化类型替换时,才能创建该类型的实例


如果您能够声明
类MyTList:MyList{}
,那么您将永远无法为
T
指定类型,因为
MyTList
不再包含该类型参数,因此您永远无法实例化
MyTList
。那不是一门很有用的课

如果不指定类型,那么唯一的其他选择就是将派生类也设置为泛型

public class MyDerivedList<T> : MyList<T>
{
}
公共类MyDerivedList:MyList
{
}
如果不是呢


您的
MyStringList
将是泛型的(因为
t
不会有硬编码类型),但这不是定义上的,因为您构建了一个非泛型类。

反过来想一想。如果没有为基本类型指定类型参数,那么
MyList
应该使用什么类型?它仍然是未定义的


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

在派生类中不显式指定类型参数的情况下,编译器如何猜测
T的类型?
?作为替代方案,您会提出什么建议?您仍然需要指定基类的类型参数,但您可以根据自己的类型参数进行指定。
public class MyDerivedList<T> : MyList<T>
{
}