【发布时间】:2010-12-22 23:50:51
【问题描述】:
为什么 C# 泛型不能像在 C++ 模板中那样从泛型类型参数之一派生?我的意思是我知道这是不可能的,因为 CLR 不支持,但是为什么呢?
我知道 C++ 模板和 C# 泛型之间的巨大差异 - 前者是编译时实体,必须在编译期间解决,而后者是一流的运行时实体。
不过,我没有看到原因为什么 CLR 设计者没有提出最终使 CLR 泛型类型能够从其泛型类型参数之一派生的方案。毕竟,这将是一个非常有用的功能,我个人非常想念它。
编辑:
我想知道一个核心问题,解决这个问题会在实施此功能时付出如此高昂的代价,从而证明它尚未实施。例如,检查这个虚构的声明:
class C<T> : T
{
}
正如 Eric Lippert 所注意到的,如果“如果 T 是结构怎么办?如果 T 是密封类类型怎么办?如果 T 是接口类型怎么办?如果 T 是 C 怎么办?!如果 T 是从 C 派生的类?如果 T 是具有抽象方法的抽象类型怎么办?如果 T 的可访问性低于 C 怎么办?如果 T 是 System.ValueType 怎么办?(你能有一个从 System.ValueType 继承的非结构吗?) System.Delegate、System.Enum 等呢?"
随着 Eric 的继续,“这些都是简单明了的”。的确,他是对的。我对一些既不简单也不明显的问题的具体示例感兴趣,这很难解决。
【问题讨论】:
-
C++ 比 C# 更复杂的原因是相互关联的,以及为什么您可以在 C++ 中完成您在 C# 中无法完成的事情。这就是为什么在可预见的未来,有些人会想用 C# 以外的东西做一些项目。
-
我不明白:C# 编译器不应该在实际尝试实例化给定模板时已经知道这些问题的答案吗?例如,拥有类 C
: T 并尝试在我的代码中编写 C i = new C () ,编译器不应该表现得好像我有一个类 C_int : int 和首先尝试 C_int i = new C_int() ? (请注意,在后一种情况下,编译器将抛出错误“不能从密封类 int 派生”——但它确实处理了这种情况)。为什么在尝试实例化模板之前必须回答所有这些问题?