为啥这些“特殊类”?

Posted

技术标签:

【中文标题】为啥这些“特殊类”?【英文标题】:Why exactly are these "Special Classes"?为什么这些“特殊类”? 【发布时间】:2015-05-06 09:07:16 【问题描述】:

在阅读this question 询问究竟是什么“特殊课程”之后,我留下了一个问题,为什么选择了六个课程 System.ObjectSystem.ArraySystem.DelegateSystem.EnumSystem.ValueType 并hard-coded 作为特殊类,防止它们被用作泛型类或方法的约束。

很容易理解为什么System.Object 在里面;所有类都继承System.Object,因此无需将其包含为约束。我不清楚的是为什么其他人被选为这个特殊课程类别的一部分。

PS:当尝试将特殊类用作约束时,会引发编译错误 CS0702。

【问题讨论】:

所有其他都是非典型继承树的根,它们具有特殊的语言支持。 @Damien_The_Unbeliever:很公平。我想指出,在某些典型情况下,其中一些约束可能有用。举个例子,一个方法要求参数是Enum 类型。受此限制,编写具有Enum 约束的泛型方法是不可能的,除非想使用类似Unconstrained Melody 中使用的Jon Skeet 之类的变通方法。诚然,即使他们有正当理由想要使用这些“特殊类”中的任何一个作为约束,也不是每个人都有能力做这些变通方法。 我认为他们并没有预见到这些类型在泛型中的用途很多(尽管我同意我不止一次想用枚举来做它们)而且我认为在替代方案中,你如果您确实允许它们,则必须实施许多额外的规则-即您仍然必须特别对待它们,因为例如ValueType 是一个引用类型,但从它派生的所有实际实例都是值类型。 【参考方案1】:

在将泛型约束甚至泛型添加到 .NET 框架并将对它们的支持添加到 C# 语言之前,这些类已经不同。

他们每个人的共同点是从他们那里继承不同于其他类型:

System.Object:你不能在 C# 中继承 this。

System.Array您可以通过创建现有类型的数组(Array x = new int[2]; 等)来继承它

System.Delegate您通过创建delegate(然后派生自MulticastDelegate,也是一种“特殊类型”,派生自Delegate)来继承它。 p>

System.Enum:你可以通过创建一个enum来继承它。

System.ValueType你可以通过创建一个struct来继承它。

现在,请注意,除了new() 之外,通用约束都与接口的继承或实现有关(在许多方面类似于继承)。事实上,其他限制是不能使用指针类型,也不能使用密封类型;无论如何都不能拥有派生类型的两种情况(尽管禁止密封类型主要是因为您可能在不需要时创建泛型类型或方法,并且试图保护您免受自己的侵害) .

因此,当遇到有关继承的特殊情况时,基于继承特性(作为约束)的代码本身可能不得不涉及特殊情况。这些特殊情况以最简单的方式处理:禁止它们。

在许多情况下,价值也较小:

System.Object: 由于唯一不能转换为System.Object 的类型是指针类型,而且这些类型无论如何都不能用作泛型参数,因此任何此类约束都是多余的。

System.Array您可以根据元素类型定义:void DoSomethingWithArray<T>(T[] array) 等。

System.Delegate: 这样会很有用,虽然在很多情况下我们可以根据参数和/或返回类型来定义,但有些情况下这并不能解决。

System.Enum:会很有用。

System.ValueType:已处理;约束为struct。相反,我们也可以限制为class 来排除这种情况,因此我们实际上有一个“不继承自...”选项,否则我们没有。

这并不是要否认能够以 DelegateMulticastDelegateEnum 进行约束是没有用的(可能大多数情况下,我们 Enum),而是为了证明额外的工作是合理的覆盖这些类型,其他人几乎不会或根本没有好处,因此减少限制的好处会减少。

【讨论】:

以上是关于为啥这些“特殊类”?的主要内容,如果未能解决你的问题,请参考以下文章

构建自包含类

C++-特殊类设计-单例模式

特殊类设计

特殊类设计

特殊类设计

特殊类设计