为了账号安全,请及时绑定邮箱和手机立即绑定

为什么C#泛型不能像C ++模板那样从其中一个泛型类型参数派生出来?

为什么C#泛型不能像C ++模板那样从其中一个泛型类型参数派生出来?

蝴蝶刀刀 2019-11-18 14:19:20
为什么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)继续所说的那样,“ 那些是容易的,显而易见的 ”。的确,他是对的。我对一些既不容易也不明显的问题的具体例子感兴趣,这很难解决。
查看完整描述

3 回答

?
胡说叔叔

TA贡献1804条经验 获得超8个赞

好吧,首先问问自己可能有什么问题class C<T> : T { }。立刻想到了很多事情:

如果T是一个结构怎么办?如果T是密封类类型怎么办?如果T是接口类型怎么办?如果T是C<T>?如果T是从中派生的类C<T>怎么办?如果T是具有抽象方法的抽象类型怎么办?如果T具有比C少的可访问性怎么办?如果T是System.ValueType怎么办?(您可以有一个继承自System.ValueType的非结构吗?)System.Delegate,System.Enum等如何?

这些是简单,显而易见的。提议的功能实际上打开了数百个(如果不是数千个)关于类型与其基类型之间的交互的更微妙的问题,所有这些问题都必须仔细指定,实现和测试。毫无疑问,我们会错过某些内容,从而在将来造成重大更改,或者使运行时受实现定义的行为约束。

成本将是巨大的,因此收益最好是巨大的。我在这里没有看到巨大的好处。


查看完整回答
反对 回复 2019-11-18
?
慕码人2483693

TA贡献1860条经验 获得超9个赞

好吧,如果您不喜欢我以前的回答,那么让我们采取另一种方法。

你的问题的先决条件是谎言:我们需要一个理由执行一个功能。相反,我们需要一个非常非常好的理由来实现任何功能。功能的前期成本,维护成本和机会成本非常昂贵。(也就是说,您花在功能X上的时间就是您不能花在执行功能Y上的时间,这可能会阻止您执行功能Z。)为了负责任地为我们的客户和利益相关者提供价值,我们无法实施所有功能有人碰巧喜欢

不能由运行时设计者来证明为什么他们没有实现您认为特别好的功能。根据功能的成本和对用户的好处来对功能进行优先级排序,并且用户并没有完全要求我进行此类继承。这个特殊功能将极大地改变类型系统的分析在运行时的工作方式,对使用泛型的每种语言产生深远的影响,并且对我来说几乎没有好处。

我们在用C ++编写的编译器中使用这种继承,并且所生成的代码难以理解,难以维护且难以调试。我一直在尽力逐步消除这样的代码。我反对在C#中启用相同类型的错误模式,除非这样做具有巨大的吸引力。

以令人信服的方式描述巨大利益的任务是由想要该功能的人员而不是必须实施该功能的人员承担。那么,什么是引人注目的收益?


查看完整回答
反对 回复 2019-11-18
?
HUX布斯

TA贡献1876条经验 获得超6个赞

可以帮助的代码示例:


public class SpecialDataRow<T> : T where T : DataRow

{

    public int SpecialFactor { get; set; }

}

这将使您能够从DataRow以及任何派生的DataRows(如键入的数据集生成的数据行)中创建“特殊”行


我没有看到其他方式如何编码这样的类


查看完整回答
反对 回复 2019-11-18
  • 3 回答
  • 0 关注
  • 694 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信