2010-02-24 98 views
9

MSDN System.Enum定义为一个抽象类:为什么我无法从System.Enum抽象类派生?

[SerializableAttribute] 
[ComVisibleAttribute(true)] 
public abstract class Enum : ValueType, IComparable, IFormattable, IConvertible 

而且还MSDN做出抽象类这样的表述:

一个抽象类不能被实例化 。抽象类的目的是为多个派生类可以共享的基类定义一个通用的定义。

但我根本无法从System.Enum派生。根据Jeffery Richter在他的书“CLR via C#”中的说法,C#编译器禁止这种派生。

我检查了System.Enum的成员,其中大多数是静态的,这是合理的,因为它不能实例化,静态方法不需要调用对象实例。但也有一些实例方法,例如GetHashCode()和GetTypeCode()。

所以,我的第一个问题是,如果System.Enum不能 被实例化或派生,怎么可能 这些实例方法调用? 这不是一种悖论吗?

我知道我可以用下面的 的方法来调用这些实例的 方法,但是为什么?是否有某种 的System.Enum或派生类型对象 实例是否创建?什么时候?并由谁?

public enum Days:byte { Saturday, Sunday, Monday, Tuesday, Wednesday, Thursday, Friday }; 
Days d = Days.Friday; 
d.GetTypeCode(); 
d.GetHashCode(); 
+0

天确实来自枚举...你有什么困惑? – 2010-02-24 14:08:07

回答

7

您可以从Enum(例如,

public enum MyEnum 
{ 
    // ... 
} 

将被编译到是这样的:

.class public auto ansi sealed MyEnum 
    extends System.Enum 
{ 
    // ... 
} 

中限制使用C#编译器的地方是,它不会让你手动编写的推导,而是需要您使用enum关键字当声明类型时。

至于为什么这是...我的猜测是因为枚举在CLR中有点奇怪。例如,ValueTypeEnum基本类型本身都是引用类型,而不是值类型。在封面下面有一大堆魔法,如果你强制使用关键字并防止从魔法基类派生出来,那么你就保持你的意图与魔法分离。

+0

谢谢,Greg。你的回答部分解决了我的问题。现在我想知道为什么不让我们直接扩展System.Enum? – smwikipedia 2010-02-24 09:07:52

+0

@smwikipedia - 刚刚添加我的猜测,为什么这是。你必须得到一位C#语言设计师来验证它(Eric Lippert经常在这里,所以他可能会有好运气的)。 – 2010-02-24 09:09:18

+0

谢谢,我已经给Eric Lippert发了一封邮件,希望他能很快回复。 – smwikipedia 2010-02-24 13:21:14

0

枚举值是类型为什么你不能instanctiate或从中获取。诸如GetHashCode()之类的实例方法仅用于诸如类的引用类型对象。

相关问题