不容置疑,枚举当然是值类型。不过,MSDN上有这样一句话:类 Enum 是从类 ValueType 派生而来的,即 Enum 本身是引用类型,而不是值类型。是何意思?还请高手指点一下。

解决方案 »

  1.   

    是从System.ValueType派生而来,但属于值类型。
      

  2.   

    using System;using System.Text;namespace outparameterstudy
    {
    class Program
    {

    public static void OutParam( int o)
    {
    o = 100;
    }
    static void Main(string[] args) {

    enum enumtype{a,b,c,d};
        enumtype e = enumtype.a;

    int x=0;
    Program.OutParam( x);
    Console.WriteLine("{0}",x);
    }
    }
    }我也很纳闷,对这个问题?
    为什么上面的会报错呢?
      

  3.   

    Knight94(愚翁) :是的啊,从ValueType派生来的应该是值类型,但MSDN上的那句又是什么意思呢?地址为ms-help://MS.MSDNQTR.2003FEB.2052/cpref/html/frlrfsystemenumclasstopic.htm
    liuxingjia000:枚举类型不能定义在方法中吧
      

  4.   

    我个人认为ENUM是一个类.C#里面把很多都搞成类了.比如数组也变成一个类了.可以调用类里面的方法.因为ENUM里面也有很多方法,所以我个人觉得ENUM是引用类型
      

  5.   

    你定义enum类型的位置错了,不能定义在方法内。
      

  6.   

    你看错了吧
    你看得是System.Enum这是一个class
      

  7.   

    也就是说
    System.Enum和
    enum Test
    不是同一个东西。
      

  8.   

    也就是说
    System.Enum和
    enum Test
    不是同一个东西
    是说:
    System.Enum 是一个类
    enum Test是声明一个枚举类型
    那这个枚举类型到底是什么值类型,还是应用类型
    还有:结构体也不能在方法中声明?
      

  9.   

    System.Enum 是一个类:引用类型
    enum Test是声明一个枚举类型:值类型
      

  10.   

    结构体当然不能在方法中声明。应该像愚翁所说的那样,System.Enum是引用,所定义的是值类型
      

  11.   

    System.Enum是结构!是值类型……
    即 Enum 本身是引用类型,而不是值类型。这只是你自己的错误推断,所有的值类型都从System.ValueType继承。
      

  12.   

    System.Enum是一个非常特殊的结构,他要从System.ValueType继承而不是直接定义为结构的原因是如果他直接定义为结构,则枚举类型将无法从它继承。
    但即使是这样,我们也不能创造一个类从System.ValueType继承。
      

  13.   

    to System.Enum是一个非常特殊的结构不是结构,参看其的定义
    [C#]
    [Serializable]
    public abstract class Enum : IComparable, IFormattable,
       IConvertible
    不管是值类型,还是引用类型,都是起源于System.ValueType,也就是说System.ValueType是所有类型的根本。
      

  14.   

    Ivony() :看了你的回答,更疑惑了。MSDN上有这样一句话:类 Enum 是从类 ValueType 派生而来的,即 Enum 本身是引用类型,而不是值类型。位置在ms-help://MS.MSDNQTR.2003FEB.2052/cpref/html/frlrfsystemenumclasstopic.htm中,又做什么解释呢?
      

  15.   

    不管是值类型,还是引用类型,都是起源于System.ValueType,也就是说System.ValueType是所有类型的根本。
    类型的根本是System.Object以下所述以.NET Framework 2.0为依据。System.Enum继承于System.ValueType。而所有的枚举类型又都继承于System.Enum。
    任何继承于System.ValueType的类型都是值类型。System.Enum的原形可以参考MSDN:
    http://msdn2.microsoft.com/zh-cn/library/system.enum.aspx
      

  16.   

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

  17.   

    不过从abstract来看,Enum的确不该是值类型。
    由于它是抽象的,那么他的实例只能是引用类型的(即转换为Enum存在装箱),否则无法产生虚函数和抽象函数。这样的话MSDN上的那句话就可以理解了。
      

  18.   

    主要是MSDN上的这段话“类 Enum 是从类 ValueType 派生而来的,即 Enum 本身是引用类型,而不是值类型”疑惑不解
      

  19.   

    lvony:由于它是抽象的,那么他的实例只能是引用类型的(即转换为Enum存在装箱),否则无法产生虚函数和抽象函数。
    Enum是抽象的,怎么能产生实例呢?奇怪的是,Enum继承于ValueType,为什么又会变成引用类型?为什么从Enum派生出来的枚举型又会转变为值类型?越弄越糊涂,是不是应该问问Anders Hejlsberg?可惜我认得他,他不认得我
      

  20.   

    Enum 是唯一一个从ValueType继承的引用类型。
      

  21.   

    to 有没有什么方法测试一个类型是值类型还是引用类型?use "Object.ReferenceEquals" methodref:
    http://blog.csdn.net/Knight94/archive/2006/08/11/1050901.aspx
      

  22.   

    可以肯定的是,CLR的继承模型是依赖于引用类型的,就像C++的依赖于指针一样,所以如果是值类型是绝对没有可能继承的,一旦转换为接口和基类类型,值类型都是装箱转换为引用类型来完成的。
      

  23.   

    MSDN值类型和引用类型:值类型要么是堆栈分配的,要么是在结构中以内联方式分配的。引用类型是堆分配的。引用类型和值类型都是从最终的基类 Object 派生出来的。当值类型需要充当对象时,就在堆上分配一个包装(该包装能使值类型看上去像引用对象一样),并且将该值类型的值复制给它。该包装被加上标记,以便系统知道它包含一个值类型。这个进程称为装箱,其反向进程称为取消装箱。装箱和取消装箱能够使任何类型像对象一样进行处理。
      

  24.   

    System.Enum是引用类型。
    用enum声明的枚举是值类型,都继承自System.Enum。System.Enum重写了一些基类的方法,供其派生类(用enum定义的枚举)使用。Object.ReferenceEquals方法似乎不能测试System.Enum,因为你不能直接构造System.Enum的实例。
      

  25.   

    说是从ValueType继承的都是值类型,结果Enum从ValueType继承,但却是引用类型。
      

  26.   

    是从System.ValueType派生而来,属于值类型。
      

  27.   

    其实 enum 和 System.Enum 没有任何直接关系。这可以通过 System.Enum.GetNames(Type enumType) 看出来。Enum 就是一个普通的自定义类型,它把enum作为对象进行一些操作。同时因为enum是特殊值类型,只能使用不能实例化,因此其实Enum通常是把 typeof(enum类) 作为参数的。例如:  Enum.Names(typeof(enumtype)).ForEach(delegate(string x){console.WriteLine(x);});用于打印enumtype中的所有内容。
      

  28.   

    sorry,可惜c#的编译器现在不能自动处理数组对Array的转换。上边的代码修改为:Array.ForEach(Enum.Names(typeof(enumtype)),delegate(string x){console.WriteLine(x);});即可。Enum仅仅是一个普通类型,里边定义了一些方法,而已。而enum是编译器可以认识的关键字,它可以自动把enumtype这个类型编译成一种独特的定义。下面是我打印 enum aaa{...} 的调试结果;?typeof(aaa)
    {Name = "aaa" FullName = "WindowsApplication1.Form1+aaa"}
        [System.RuntimeType]: {Name = "aaa" FullName = "WindowsApplication1.Form1+aaa"}
        base {System.Reflection.MemberInfo}: {Name = "aaa" FullName = "WindowsApplication1.Form1+aaa"}
        Assembly: {WindowsApplication1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null}
        AssemblyQualifiedName: "WindowsApplication1.Form1+aaa, WindowsApplication1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"
        Attributes: Public | NestedPublic | Sealed
        BaseType: {Name = "Enum" FullName = "System.Enum"}
        ContainsGenericParameters: false
        DeclaringMethod: “(typeof(aaa)).DeclaringMethod”引发了“System.InvalidOperationException”类型的异常
        DeclaringType: {Name = "Form1" FullName = "WindowsApplication1.Form1"}
        FullName: "WindowsApplication1.Form1+aaa"
        GenericParameterAttributes: “(typeof(aaa)).GenericParameterAttributes”引发了“System.InvalidOperationException”类型的异常
        GenericParameterPosition: “(typeof(aaa)).GenericParameterPosition”引发了“System.InvalidOperationException”类型的异常
        GUID: {0e329814-129c-3ef9-a6e7-d280111fb912}
        HasElementType: false
        IsAbstract: false
        IsAnsiClass: true
        IsArray: false
        IsAutoClass: false
        IsAutoLayout: true
        IsByRef: false
        IsClass: false
        IsCOMObject: false
        IsContextful: false
        IsEnum: true
        IsExplicitLayout: false
        IsGenericParameter: false
        IsGenericType: false
        IsGenericTypeDefinition: false
        IsImport: false
        IsInterface: false
        IsLayoutSequential: false
        IsMarshalByRef: false
        IsNested: true
        IsNestedAssembly: false
        IsNestedFamANDAssem: false
        IsNestedFamily: false
        IsNestedFamORAssem: false
        IsNestedPrivate: true
        IsNestedPublic: false
        IsNotPublic: false
        IsPointer: false
        IsPrimitive: false
        IsPublic: false
        IsSealed: true
        IsSerializable: true
        IsSpecialName: false
        IsUnicodeClass: false
        IsValueType: true
        IsVisible: false
        MemberType: NestedType
        Module: {WindowsApplication1.exe}
        Namespace: "WindowsApplication1"
        ReflectedType: {Name = "Form1" FullName = "WindowsApplication1.Form1"}
        StructLayoutAttribute: {System.Runtime.InteropServices.StructLayoutAttribute}
        TypeHandle: {System.RuntimeTypeHandle}
        TypeInitializer: null
        UnderlyingSystemType: {Name = "aaa" FullName = "WindowsApplication1.Form1+aaa"}
      

  29.   

    注意 IsClass、IsGenericType、IsInterface、IsEnum、IsSerializable、IsValueType 等。
      

  30.   

    =========================
    我们总是喜欢在那里空谈理论。就是不会有人去验证一下。很简单,如果是引用类型,作为参数传入到函数,并在函数内部修改,
    1)如果在函数外,此类型的值改变了,就是引用类型
    2)如果在函数外,此类型的值未改变了,就是值类型。public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
            }        void ModifyDay(TimeDay day)
            {
                if (day != TimeDay.Evening)
                {
                    day = TimeDay.Evening;
                }
                else
                {
                    day = TimeDay.Morning;
                }
            }        void ModifyDay2(TimeDay2 day)
            {
                if (day.ThisDay != TimeDay.Evening)
                {
                    day.ThisDay = TimeDay.Evening;
                }
                else
                {
                    day.ThisDay = TimeDay.Morning;
                }
            }        private void button1_Click(object sender, EventArgs e)
            {
                TimeDay day = TimeDay.Afternoon;            ModifyDay(day);            Console.WriteLine(day); //输出Afternoon            TimeDay2 day2 = new TimeDay2(TimeDay.Morning);
                ModifyDay2(day2);            Console.WriteLine(day2.ThisDay); //输出Evening
            }
        }    public enum TimeDay
        {
            Morning = 0,
            Afternoon = 1,
            Evening = 2
        }    public class TimeDay2
        {
            private TimeDay day;        public TimeDay2(TimeDay day)
            {
                this.day = day;
            }        public TimeDay ThisDay
            {
                get { return day; }
                set { day = value; }
            }
        }
      

  31.   

    fsxdxh(假行僧) :不容置疑,enum 定义的枚举型是值类型,但我们讨论的System.Enum到底是值类型还是引用类型。MSDN上有说明了所有的枚举继承于System.Enum,而System.Enum继承于ValueType,但又说System.Enum是引用类型,所以才有此疑问。
      

  32.   

    正如 ?typeof(aaa) 所输出的,枚举类型继承自 System.Enum,但是枚举本身不是类,不是范型,不是接口。枚举类型是独特的。而 打印 ?typeof(System.Enum) 的结果:?typeof(System.Enum)
    {Name = "Enum" FullName = "System.Enum"}
        [System.RuntimeType]: {Name = "Enum" FullName = "System.Enum"}
        base {System.Reflection.MemberInfo}: {Name = "Enum" FullName = "System.Enum"}
        Assembly: {mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089}
        AssemblyQualifiedName: "System.Enum, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
        Attributes: Public | Abstract | Serializable | BeforeFieldInit
        BaseType: {Name = "ValueType" FullName = "System.ValueType"}
        ContainsGenericParameters: false
        DeclaringMethod: “(typeof(System.Enum)).DeclaringMethod”引发了“System.InvalidOperationException”类型的异常
        DeclaringType: null
        FullName: "System.Enum"
        GenericParameterAttributes: “(typeof(System.Enum)).GenericParameterAttributes”引发了“System.InvalidOperationException”类型的异常
        GenericParameterPosition: “(typeof(System.Enum)).GenericParameterPosition”引发了“System.InvalidOperationException”类型的异常
        GUID: {c43345b9-7fed-3fc7-8fc2-7b1b82bc109e}
        HasElementType: false
        IsAbstract: true
        IsAnsiClass: true
        IsArray: false
        IsAutoClass: false
        IsAutoLayout: true
        IsByRef: false
        IsClass: false
        IsCOMObject: false
        IsContextful: false
        IsEnum: false
        IsExplicitLayout: false
        IsGenericParameter: false
        IsGenericType: false
        IsGenericTypeDefinition: false
        IsImport: false
        IsInterface: false
        IsLayoutSequential: false
        IsMarshalByRef: false
        IsNested: false
        IsNestedAssembly: false
        IsNestedFamANDAssem: false
        IsNestedFamily: false
        IsNestedFamORAssem: false
        IsNestedPrivate: false
        IsNestedPublic: false
        IsNotPublic: false
        IsPointer: false
        IsPrimitive: false
        IsPublic: true
        IsSealed: false
        IsSerializable: true
        IsSpecialName: false
        IsUnicodeClass: false
        IsValueType: false
        IsVisible: true
        MemberType: TypeInfo
        Module: {CommonLanguageRuntimeLibrary}
        Namespace: "System"
        ReflectedType: null
        StructLayoutAttribute: {System.Runtime.InteropServices.StructLayoutAttribute}
        TypeHandle: {System.RuntimeTypeHandle}
        TypeInitializer: {Void .cctor()}
        UnderlyingSystemType: {Name = "Enum" FullName = "System.Enum"}对照 IsEnum、IsValueType 可以看出 enum 的独特性。
      

  33.   

    没有仔细研究msdn。也许,msdn是描述的.net早期版本的东西,现在已经应该改写了。
      

  34.   

    在C#里,所有的类型,不管值类型还是引用类型,都是从System.Object派生出来,System.Object不是一个引用类型么……针对这些比较特殊的东东,在C#里当然有独特的规范。比如说值类型,如果所有的类型全变成引用类型,肯定是非常影响效率的,所以才有了System.ValueType类,以及从此派生出来的各种值类型。就像楼上说的,枚举类型也是一种独特的东东,你把他当成一个独特的类型来对待就OK了,不要想太多了
    其实,个人感觉吧。C#中所有的类型其实都是引用类型的,值类型通过装箱也能变得和引用类型一样的一些性质……记得以前看书的就因为初箱折箱折腾半天
    菜鸟发言,高手看了不要笑偶
      

  35.   

    typeof(System.Enum).IsValueType == falseSystem.Enum也不是一个值类型,说明它是引用类型,跟它是不是类没关系System.Enum作用是为枚举提供基类,而为枚举提供基类的作用是提供比较此类的实例的方法、将实例的值转换为其字符串表示形式的方法、将数字的字符串表示形式转换为此类的实例的方法和创建指定枚举和值的实例的方法。ValueType的定义是:
    public abstract class ValueType
    ValueType是不是类呢?也不是
      

  36.   

    不好意思
    ValueType是类,IsValueType = false