是什么让ValueType类特别?

时间:2014-01-19 05:58:10

标签: c# inheritance compiler-errors

当我尝试定义一个继承自System.ValueTypeSystem.Enum类的类时,我收到错误:

Cannot derive from special class System.ValueType

我理解错误,但我无法理解的是ValueType特殊的原因是什么?我的意思是没有关键字(如sealed)或属性来指定不能继承此类。ValueType有两个属性,SerializableComVisible但没有一个属性与此案有关。documentation说:

  

虽然ValueType是值类型的隐式基类,但不能创建直接从ValueType继承的类。相反,单个编译器提供语言关键字或构造(例如C#和Structure中的struct) ... Visual Basic中的End结构),支持创建值类型。

但它没有回答我的问题。所以我的问题是在这种情况下如何通知编译器?当我尝试创建一个继承自类的类时,编译器是否直接检查该类是ValueType还是Enum

修改:所有结构implicitly都继承自ValueType,但Enum显式继承自ValueType,那么它是如何工作的呢?编译器如何弄清楚这种情况,所有这些都是由编译器硬编码的?

3 个答案:

答案 0 :(得分:17)

  

我理解错误但是我无法理解的是什么让ValueType类变得特别?

该课程记录是特殊的。这就是它的特殊之处。

  

在这种情况下如何通知编译器?

编译器编写者在编写编译器之前会阅读文档。

  

当我尝试创建一个继承自类的类时,编译器是否直接检查该类是ValueType还是Enum?

  

此外,所有结构都隐式继承自ValueType,但Enum类显式继承自ValueType,那么它是如何工作的呢?

它运作良好。

  

是否所有这些特殊情况都硬编码到编译器中?

  

创建一个属性以指定此类是特殊的并且不能继承而不是硬编码是不是更合适?

不,不是。这意味着第三方也可以创建一个特殊类型,在继承时需要编译器进行特殊处理。然后,第三方将如何修改编译器以实现这些规则?

答案 1 :(得分:3)

System.ValueType是编译器的特殊处理类,用于注释值类型。编译器使用它的方式不同,因为值类型对象的处理方式与引用类型对象不同。我认为this series of blog posts可以对价值和参考类型之间的差异做出一些澄清。 This MSDN post describes the common cases of value reference types以便您可以轻松地对每种类型进行分类。

您的问题的答案在.NET Common Type System中。 如果您想创建自己的值类型类,我建议您创建一个结构。复制自(普通TYP系统,结构参考)(http://msdn.microsoft.com/en-us/library/zcx1eb1e%28v=vs.110%29.aspx#Structures):

  

结构是一种从System.ValueType隐式派生的值类型,而System.Object又派生自Boolean。 ...在.NET Framework类库中,所有原始数据类型(Byte,DateTime Char,DecimalDoubleInt16,{{1 }},Int32Int64SByteSingleUInt16UInt32UInt64)被定义为结构

     

与类类似,结构定义数据(结构的字段)和可以对该数据执行的操作(结构的方法)。 ...

     

值类型在几个方面也与类不同。首先,虽然隐式继承自System.ValueType ,但无法直接从任何类型继承。同样,所有值类型都是密封的,这意味着不能从它们派生其他类型。 ...

     

对于每种值类型,公共语言运行库提供相应的盒装类型,这是一个与值类型具有相同状态和行为的类。 ... 定义值类型时,您定义的是盒装类型和未装箱类型

希望我帮忙!

答案 2 :(得分:3)

Microsoft不发布其C#编译器源代码,因此我们只能猜测检查是否嵌入在编译器级别。

Mono的C#编译器在编译时执行这种检查,你可以在Class.ResolveBaseTypes方法的第2790行看到,

https://github.com/mono/mono/blob/master/mcs/mcs/class.cs