为什么C#泛型不能像C++模板中那样从泛型类型参数中派生出来?我的意思是我知道这是不可能的,因为CLR不支持这个,但为什么呢?
我知道C++模板和C#泛型之间的深刻差异 - 前者是编译时实体,必须在编译期间解析,而后者是一流的运行时实体.
不过,我没有看到的原因,为什么CLR的设计者并没有拿出一个方案,该方案将最终使CLR泛型类型从泛型类型参数的一个派生.毕竟,这将是非常有用的功能,我个人非常想念它.
编辑:
我想知道一个核心问题,解决这个问题会产生如此高的代价来实现这个功能,这个功能证明它还没有得到实施.例如,检查这个虚构的声明:
class C: T { }
正如Eric Lippert已经注意到" 如果T是一个结构怎么办?如果T是一个密封的类型怎么办?如果T是一个接口类型怎么办?如果T是C怎么办?如果T是从C语言中得到什么怎么办?"如果T是带抽象方法的抽象类型?如果T的可访问性低于C怎么办?如果T是System.ValueType怎么办?(你能否有一个继承自System.ValueType的非结构?)System.Delegate怎么样? System.Enum等等? "
正如埃里克继续说的那样," 那些是容易的,显而易见的 ".的确,他是对的.我感兴趣的是一个既不容易也不明显的问题的具体例子,这个问题很难解决.
好吧,首先问问自己可能出现的问题class C
.马上就会想到很多东西:
如果T是结构怎么办?如果T是密封类型怎么办?如果T是接口类型怎么办?如果T是C
什么?!如果T是一个派生自的类C
怎么办?如果T是带抽象方法的抽象类型怎么办?如果T的可访问性低于C,该怎么办?如果T是System.ValueType怎么办?(你有一个从System.ValueType继承的非结构吗?)System.Delegate,System.Enum等等怎么样?
这些是简单明了的.所提出的特征打开了数百个,如果不是数千个关于类型与其基类型之间的相互作用的更微妙的问题,所有这些都必须仔细指定,实施和测试.毫无疑问,我们会错过一些,从而导致未来发生重大变化,或者通过实现定义的行为来限制运行时.
成本将是巨大的,因此效益最好是巨大的.我没有看到这里的巨大好处.
好吧,如果你不喜欢我以前的答案,那么让我们采取不同的策略.
你的问题的先决条件是谎言:我们需要一个理由来不执行一个功能.相反,我们需要一个非常非常好的理由来实现任何功能.它们的前期成本,维护成本和机会成本非常昂贵.(也就是说,您在功能X上花费的时间是您不能花费在功能Y上的时间,这可能会阻止您使用功能Z.)为了负责任地为我们的客户和利益相关者提供价值,我们无法实现每项功能有人碰巧喜欢.
运行时设计师无法证明为什么他们没有实现您觉得特别好的功能.根据成本与用户的利益优先考虑功能,用户并没有完全按照我的要求进行这种继承.这个特殊的功能将大大改变类型系统的分析在运行时的工作方式,对消耗泛型的每种语言都有深远的影响,而且在我看来提供的好处很少.
我们在编译器中使用这种继承 - 用C++编写 - 并且生成的代码很难遵循,难以维护,并且难以调试.我一直在尽力逐步消除这样的代码.我反对在C#中启用相同类型的错误模式,除非这样做有非常令人信服的好处.
以令人信服的方式描述这种巨大利益的任务是针对想要该功能的人,而不是那些必须实现它的人.那么有什么吸引人的好处呢?
代码示例,这可能会有所帮助:
public class SpecialDataRow: T where T : DataRow { public int SpecialFactor { get; set; } }
这样就可以从DataRow和任何派生的DataRows(如类型化生成的数据集)中创建"特殊"行.
我没有看到任何其他方式如何编写这样的类