locked
Enumeration and its underlying type C# RRS feed

  • Question

  • Hi everyone eventually reading this :)

    Consider this enum declaration:

    [Flags]
    private enum FormStates : System.Int16
    {
        UseProxy = 0,
        NoProxy = 2
    }
    If I set enum underlying type to System.Int16 I got error CS1008 (VS2008)
    Error 73 Type byte, sbyte, short, ushort, int, uint, long, or ulong expected

    If I provide short instead of Int16 then there is no error.

    As short is Int16 there shouldn't be this error or I am wrong?

    Same if I provide Int32 and not long.

    What is an issue here?
    Tuesday, March 30, 2010 12:47 PM

Answers

  • They are interchangeable, provided the context is valid.

     

     
        enum Values : short
        {
            Droid,
            Druid
        }
    
    
        enum Values : Int16
        {
            Droid,
            Druid
        }

     

    The first example is valid, while the second throws a compiler error.  The second example is trying to inherit from a type that derives from System.ValueType, which is strictly prohibited.  Use of the keyword to causes the compiler to allow you to do it.  This is one way how the control over how types that inherit from System.ValueType are allowed to be created.

        class Class1 : System.ValueType
        {
        }
    The compiler expressly prohibits this.  I find the error message amusing.  It declares the type as "special", which is what I have been trying to say all along.  This behavior is "by design".

    As I noted before, the compiler behavior in this scenario also makes your code more platform independent.

    Rudy  =8^D

     


    Mark the best replies as answers. "Fooling computers since 1971."
    • Marked as answer by RSSole Friday, April 2, 2010 11:14 AM
    Thursday, April 1, 2010 1:04 PM
    Moderator
  • The grammar is correct. C# specification explicitly states that the enum's underlying type "must be byte, sbyte, short, ushort, int, uint, long or ulong".
    Monday, April 5, 2010 1:56 AM

All replies

  • Becuse Enum class underlying type is any integral type except Char - and Int16 isn't an integral type.

    Please see:

    http://msdn.microsoft.com/en-us/library/exx3b86w.aspx (Integral Types Table (C# Reference))

    http://msdn.microsoft.com/en-us/library/system.enum.aspx (Enum Class (System))


    My Blog - MSDN Complement By Providing Visual C# Walkthroughs and Sample Codes - Founded In February 24, 2010
    Tuesday, March 30, 2010 1:14 PM
  • Int16 is certainly an integral type - "short" is just an alias for it.

    This appears to be a quirk of the C# compiler or an oversight - it exects the alias types in the clause, not the full system types there.

     


    Convert between VB, C#, C++, & Java (http://www.tangiblesoftwaresolutions.com)
    Tuesday, March 30, 2010 1:37 PM
  • Well, technically speaking System.Int16 is a value type (structure) which has one 'short' field. You cannot use value type as enum underlying type - IMO that's why you get the error.
    This is definitely the reason why you cannot do this in IL language.

    However I can imagine that a .NET language could choose to hide this technical difference from developer in that language. C# didn't choose to hide it in this case. If you want to know why, I'd recommend to ask on C# language forum.

    -Karel

    Tuesday, March 30, 2010 4:23 PM
  • "short" and "System.Int16" are one and the same.

    They are both value types - "short" is just an alias for the System.Int16 value type.

    I'm not sure what you mean when you say that System.Int16 has one 'short' field - it doesn't - it has the same members and fields as 'short' since it's the same type.

     


    Convert between VB, C#, C++, & Java (http://www.tangiblesoftwaresolutions.com)
    • Marked as answer by RSSole Wednesday, March 31, 2010 7:22 AM
    • Unmarked as answer by RSSole Friday, April 2, 2010 11:13 AM
    Tuesday, March 30, 2010 4:36 PM
  • You are right that C# considers 'short' as alias for 'System.Int16' (as this MSDN doc mentions). Therefore this particular question should be probably raised on C# forum.

    I interpreted 'short' as equivalent to 'signed 16-bit integer' which is named 'int16' in IL/CLI, where it is indeed different: int16 and System.Int16 are tight together, but technically they are not the same in CLI. int16 corresponds to the unboxed value type System.Int16.
    Note that System.Int16 cannot be used at many places where int16 (ELEMENT_TYPE_I2) can be used (e.g. in signatures and custom attributes encoding).
    On the other hand int16 (ELEMENT_TYPE_I2) cannot be used for method calls, because it is not a BCL type. That's where System.Int16 comes handy.

    You can also confirm that by running ildasm.exe on mscorlib.dll. Here's how System.Int16 is defined:

    .class public sequential ansi serializable sealed beforefieldinit System.Int16
           extends System.ValueType
           implements System.IComparable,
                      System.IFormattable,
                      System.IConvertible,
                      class System.IComparable`1<int16>,
                      class System.IEquatable`1<int16>
    {
        .field assembly int16 m_value // Note: This is not recursive definition
        // And more ...
    }

    Sorry for the confusion,
    -Karel

    Tuesday, March 30, 2010 8:01 PM
  • Thanks, your and David's explanation is helpful.

    Also, it worths nothing to re-post this at c# forum.

    Just to check out what will come up there :)
    Wednesday, March 31, 2010 7:24 AM
  • Hi everyone eventually reading this :)

    I've already posted same question at http://social.msdn.microsoft.com/Forums/en-US/clr/thread/70b8b7f1-a561-4117-8c78-41880e723da2/
    With providing some useful insights, guys also suggested re-posting here.

    Consider this enum declaration:

    [Flags]
    
    private enum FormStates : System.Int16
    
    {
    
        UseProxy = 0,
    
        NoProxy = 2
    
    }
    
    
    If I set enum underlying type to System.Int16 I got error CS1008 (VS2008)
    Error 73 Type byte, sbyte, short, ushort, int, uint, long, or ulong expected

    If I provide short instead of Int16 then there is no error.

    As short is Int16 there shouldn't be this error or I am wrong?

    Same if I provide Int32 and not long.

    What is an issue here?

    Thanks.
    • Merged by Rudedog2Moderator Thursday, April 1, 2010 12:54 PM same topic, OP request
    Wednesday, March 31, 2010 7:32 AM
  • You cannot inherit from any class that derives from System.ValueType.  The designers of the Base Class Library did not want to provide developers with a means to define their own primitive Value Types.  They wanted to eliminate the confusions of the past that arose when developers could define their own value types, and force everyone to use the same primitive types. 

    Problems arose when you could not determine which "Integer" type that you should use.  In languages like C++, the code is compiled in multiple passes.  If you wish to use code from a library, then you had to reference the source code in such a way that the compiler would compile those primitive types first.  Guess what happens when code from one library you wish to use references a value type named "Integer", and another library you wish to use needs a different type with the  same name "Integer".

    The BCL designers recognized the need and desire of developers to define their own numerical data types and structures.  So a tightly controlled mechanism was put in place to allow developers to define their own types that inherit from System.ValueType.  This mechanism is implemented through the use of keywords: i.e. struct, enum, int, short, long.

    Rudy  =8^D


    Mark the best replies as answers. "Fooling computers since 1971."
    Wednesday, March 31, 2010 2:23 PM
    Moderator
  • You cannot inherit from any class that derives from System.ValueType.  The designers of the Base Class Library did not want to provide developers with a means to define their own primitive Value Types.  They wanted to eliminate the confusions of the past that arose when developers could define their own value types, and force everyone to use the same primitive types. 

    Problems arose when you could not determine which "Integer" type that you should use.  In languages like C++, the code is compiled in multiple passes.  If you wish to use code from a library, then you had to reference the source code in such a way that the compiler would compile those primitive types first.  Guess what happens when code from one library you wish to use references a value type named "Integer", and another library you wish to use needs a different type with the  same name "Integer".

    The BCL designers recognized the need and desire of developers to define their own numerical data types and structures.  So a tightly controlled mechanism was put in place to allow developers to define their own types that inherit from System.ValueType.  This mechanism is implemented through the use of keywords: i.e. struct, enum, int, short, long.

    Rudy  =8^D


    Mark the best replies as answers. "Fooling computers since 1971."
    Wednesday, March 31, 2010 2:24 PM
    Moderator
  • In languages like C++, the code is compiled in multiple passes.

    Actually, C/C++ is compiled in a single pass.

    It's languages like C#, VB, and Java that are compiled in multiple passes.


    Convert between VB, C#, C++, & Java (http://www.tangiblesoftwaresolutions.com)
    Wednesday, March 31, 2010 4:50 PM
  • You cannot inherit from any class that derives from System.ValueType.  The designers of the Base Class Library did not want to provide developers with a means to define their own primitive Value Types.  They wanted to eliminate the confusions of the past that arose when developers could define their own value types, and force everyone to use the same primitive types. 

    Problems arose when you could not determine which "Integer" type that you should use.  In languages like C++, the code is compiled in multiple passes.  If you wish to use code from a library, then you had to reference the source code in such a way that the compiler would compile those primitive types first.  Guess what happens when code from one library you wish to use references a value type named "Integer", and another library you wish to use needs a different type with the  same name "Integer".

    The BCL designers recognized the need and desire of developers to define their own numerical data types and structures.  So a tightly controlled mechanism was put in place to allow developers to define their own types that inherit from System.ValueType.  This mechanism is implemented through the use of keywords: i.e. struct, enum, int, short, long.

    Rudy  =8^D


    Mark the best replies as answers. "Fooling computers since 1971."


    That still doesn't explain why using "short" is ok, but "System.Int16" is not - they are one and the same.

    It's just a quirk in the compiler - in many other places where an integer is required (e.g., argument types, etc.) you can specify either the alias type or the System type without a problem.  The fact that the compiler has a problem with the non-aliased System integer types on enum declarations could even be regarded as a bug.

     


    Convert between VB, C#, C++, & Java (http://www.tangiblesoftwaresolutions.com)
    Wednesday, March 31, 2010 5:01 PM
  • Hi everyone eventually reading this :)

    Consider this enum declaration:

    [Flags]
    
    private enum FormStates : System.Int16
    
    {
    
        UseProxy = 0,
    
        NoProxy = 2
    
    }
    
    
    If I set enum underlying type to System.Int16 I got error CS1008 (VS2008)
    Error 73 Type byte, sbyte, short, ushort, int, uint, long, or ulong expected

    If I provide short instead of Int16 then there is no error.

    As short is Int16 there shouldn't be this error or I am wrong?

    Same if I provide Int32 and not long.

    What is an issue here?


    This sounds like a small compiler bug (small becuase its easy to workaround).

    Here is what MSDN says "The C# type keywords and their aliases are interchangeable."

     

    Cap'n

     

    Wednesday, March 31, 2010 5:18 PM
  • In languages like C++, the code is compiled in multiple passes.

    Actually, C/C++ is compiled in a single pass.

    It's languages like C#, VB, and Java that are compiled in multiple passes.


    Convert between VB, C#, C++, & Java (http://www.tangiblesoftwaresolutions.com)

    Actually this all depends upon what is meant by "pass".

    No compiler reads the source file more than once for example, pass doesn't refer to that.

    But some compilers scan over the internal parse tree and symbol table in distinct phases or passes.

    I know that C insists that all declares physically precede thier use in the source code, not so for C# (or PL/I and some other languages), in these languages the system reads all source and constructs symbol table and parse tree as it goes, at the same time. Then it performs a second phase which resolves all references in the parse tree to declared symbols in symbol table. Sometimes there are other phases too (optimize for example).

    C is definitely single pass, but I'm no C++ coder; if you can reference a variable BEFORE the appearance of its declaration in a language, then that's not a single pass language.

    Cap'n

     

    Wednesday, March 31, 2010 5:25 PM
  • Yes, it does. They are not as identical as you assume.  One is a type, and the other is a keyword. 

    It is not a quirk in the compiler.  It is "by design".  And I explained why it is right at the beginning.

    You cannot inherit from any class that derives from System.ValueType

    But, they allow you to use the keyword to control just how much freedom you have when declaring types derived from System.ValueType.  The same thinking applies when you try to apply generic constraints on Value Types.  You are restricted to the use of only the "struct" keyword.


    Mark the best replies as answers. "Fooling computers since 1971."
    Wednesday, March 31, 2010 5:37 PM
    Moderator
  • short is System.Int16 - i.e., "short" derives from System.ValueType.

    The fact that the compiler lets you use "short" here and not "System.Int16" is a quirk of the compiler (perhaps not a bug, but a quirk).

    The comparison you make to generic constraints is not the same thing at all - the keyword 'struct' in a generic constraint is not used to specify a type, and 'struct' is not a type alias like 'short'.

     


    Convert between VB, C#, C++, & Java (http://www.tangiblesoftwaresolutions.com)
    Wednesday, March 31, 2010 6:10 PM
  • You are looking at just one side of the coin, just one use of the keywords.  The intent is to prevent your using names of any types that derive from System.ValueType when declaring other types.  The original intent is to provide a tightly controlled mechanism that allows you to declare types that inherit from System.ValueType.

    By restricting you to using only the keywords, it also makes the code more platform independent, BTW.

    Rudy  =8^D


    Mark the best replies as answers. "Fooling computers since 1971."
    Wednesday, March 31, 2010 6:26 PM
    Moderator
  • I don't know whether moderator can combine two topics as "original of this cloned one" is on .NET framework forum... :)

    User Captain Kernel mentioned what MSDN says "The C# type keywords and their aliases are interchangeable."

    I got confused as until I've encountered this, I thought exactly that, keyword and underlying type is interchangeable.

    I can't agree on that "restricting to using only the keywords it makes code more platform independent". It is framework (CLR, BCL, JIT compiler etc) that (should) make it platform independent within (ugly but simple said) "scope of framework".

    One more thing, you say "intent to preventing using names of any types that derive from System.ValueType...",
    however, if we consider that we can provide, not to say "base type" but "underlying type" of enumeration to be short, byte, long etc,
    and those are primitive value types (and not user defined value types, more about them here)
    why it is not allowed using them interchangeably if they are interchangeable by docs.

    After all, I consider this rather interesting for discussion than as some hunt for bugs, quirks in compiler or something else. :)

    Regards,
    Thursday, April 1, 2010 8:21 AM
  • They are interchangeable, provided the context is valid.

     

     
        enum Values : short
        {
            Droid,
            Druid
        }
    
    
        enum Values : Int16
        {
            Droid,
            Druid
        }

     

    The first example is valid, while the second throws a compiler error.  The second example is trying to inherit from a type that derives from System.ValueType, which is strictly prohibited.  Use of the keyword to causes the compiler to allow you to do it.  This is one way how the control over how types that inherit from System.ValueType are allowed to be created.

        class Class1 : System.ValueType
        {
        }
    The compiler expressly prohibits this.  I find the error message amusing.  It declares the type as "special", which is what I have been trying to say all along.  This behavior is "by design".

    As I noted before, the compiler behavior in this scenario also makes your code more platform independent.

    Rudy  =8^D

     


    Mark the best replies as answers. "Fooling computers since 1971."
    • Marked as answer by RSSole Friday, April 2, 2010 11:14 AM
    Thursday, April 1, 2010 1:04 PM
    Moderator
  • Yes, it does. They are not as identical as you assume.  One is a type, and the other is a keyword. 

    It is not a quirk in the compiler.  It is "by design".  And I explained why it is right at the beginning.

    You cannot inherit from any class that derives from System.ValueType

    But, they allow you to use the keyword to control just how much freedom you have when declaring types derived from System.ValueType.  The same thinking applies when you try to apply generic constraints on Value Types.  You are restricted to the use of only the "struct" keyword.


    Mark the best replies as answers. "Fooling computers since 1971."


    I disagree Rudedog.

    Who's inherting anything?

    Just because the syntax uses a colon ':' character does not mean that "inheritance" is involved in this.

    The language designer simply chose this grammar for convenience, I think you are attaching too much significance to the colon syntax.

    Cap'n

     

    Thursday, April 1, 2010 11:53 PM
  • They are interchangeable, provided the context is valid.

     

     
    
        enum Values : short
    
        {
    
            Droid,
    
            Druid
    
        }
    
    
    
    
    
        enum Values : Int16
    
        {
    
            Droid,
    
            Druid
    
        }

     

    The first example is valid, while the second throws a compiler error.  The second example is trying to inherit from a type that derives from System.ValueType, which is strictly prohibited.  Use of the keyword to causes the compiler to allow you to do it.  This is one way how the control over how types that inherit from System.ValueType are allowed to be created.

     

        class Class1 : System.ValueType
    
        {
    
        }
    
    
    The compiler expressly prohibits this.  I find the error message amusing.  It declares the type as "special", which is what I have been trying to say all along.  This behavior is "by design".

     

    As I noted before, the compiler behavior in this scenario also makes your code more platform independent.

    Rudy  =8^D

     


    Mark the best replies as answers. "Fooling computers since 1971."


    True, and the compiler also prohibits this:

    class Class1 : short
        {
    
        }
    

    Cap'n

     

    Thursday, April 1, 2010 11:57 PM
  • You are looking at just one side of the coin, just one use of the keywords.  The intent is to prevent your using names of any types that derive from System.ValueType when declaring other types.  The original intent is to provide a tightly controlled mechanism that allows you to declare types that inherit from System.ValueType.

    By restricting you to using only the keywords, it also makes the code more platform independent, BTW.

    Rudy  =8^D


    Mark the best replies as answers. "Fooling computers since 1971."


    Here is more:

    I get two different compiler errors when I use :System.ValueType on an enum and a class.

    For an enum I get: Type, byte, sbyte, short, ushort, int, uint, long or ulong expected.

    For a class I get: TestC cannot derive from special class 'System.ValueType'.

    Now if you were correct, we'd see the same error generated surely? But we don't because the enum and its colon syntax has nothing to do with inheritance.

    In my view this is a real but tiny, compiler (or perhaps grammar) bug.

    Cap'n

     

    Friday, April 2, 2010 12:04 AM
  • Ok, I've marked both your replies as answers as in both posts we can find something what leads to overall conclusion.

    By imposing such limitation as noted on behalf of compiler language designers introduced limitation on which type enumeration can "inherit", that is has as underlying type and ensured that value type cannot be inherited from.

    But again, in terms of "inheritance" syntax and keywords as type aliases they have gone too far and made, possibly unintentional, restriction which if we guide by concept of keyword as alias for type seems as bug or quirk or...whatever.

    It seems that such behavior came up from using inheritance syntax for specifying underlying type of enumeration.

    Anyway, strictly from my own point speaking, not allowing Int16 to be used in place where short could be IS mistake. I wouldn't consider that as confusing (as someone could say that it can confuse someone not knowing about enumeration and specifying underlying type) because you should know about enumeration as it is one of language essentials. After all, you will find in many places (books, blogs, articles whatever) recommending usage of CLR type names instead of language keywords.

    Thanks and regards

    Friday, April 2, 2010 11:33 AM
  • As I mentioned earlier, this discussion belongs to C# forum (just moved the thread).

    If you think it is a bug in C# compiler (and I personally agree with it, although I am not C# expert), please file it on MS Connect (and post link here). That way you will get official answer from C# team.

    -Karel

    Friday, April 2, 2010 4:49 PM
  • After all, you will find in many places (books, blogs, articles whatever) recommending usage of CLR type names instead of language keywords.


    The only recommendation of that kind I would agree with is when using a type name in a method name.

    For example, don't name a method GetShort() but GetInt16()

    Friday, April 2, 2010 11:13 PM
  • in C++/CLI this compiles without problem (VS2008)

    public enum class States: Int16

    Saturday, April 3, 2010 2:09 AM
  • After all, you will find in many places (books, blogs, articles whatever) recommending usage of CLR type names instead of language keywords.


    The only recommendation of that kind I would agree with is when using a type name in a method name.

    For example, don't name a method GetShort() but GetInt16()


    Yeah, ok but that is whole another discussion anyway and is not focus of topic, I've mentioned that just...I don't know :) just to mention it :)

    Hu's reply is something truly interesting :)
    Saturday, April 3, 2010 1:47 PM
  • How bizarre!

    short and Int16 are the same thing.

    Saturday, April 3, 2010 2:51 PM
  • How bizarre!

    short and Int16 are the same thing.


    I checked the C# language grammar, and can tell you that the compiler is behaving correctly. The grammar is wrong, because it says the type specified in an enum must be one of the simple types, but it fails to say "or their aliases".

    So I do now think that technically this is a small error in the C# grammar but not the compiler because it is correctly adhering to that grammar.

    Cap'n

    Sunday, April 4, 2010 12:25 AM
  • The grammar is correct. C# specification explicitly states that the enum's underlying type "must be byte, sbyte, short, ushort, int, uint, long or ulong".
    Monday, April 5, 2010 1:56 AM
  • KwyThe grammar is correct. C# specification explicitly states that the enum's underlying type "must be byte , sbyte , short , ushort , int , uint , long or ulong ".
    Keywords, all.

    Mark the best replies as answers. "Fooling computers since 1971."
    Monday, April 5, 2010 12:37 PM
    Moderator

  • in C++/CLI this compiles without problem (VS2008)

     

    public
     enum
     class
     States: Int16
    

    This is exactly why the designers wanted to prohibit developers from defining their own ValueTypes by inheriting from them.  Consider the mess that occurs when you start overriding the base class methods.  Consider the mess that is created when you need to use 2 different libraries that each define their own Value Types, which are different from what you defined or need. 

    Mark the best replies as answers. "Fooling computers since 1971."
    Monday, April 5, 2010 12:41 PM
    Moderator
  • The grammar is correct. C# specification explicitly states that the enum's underlying type "must be byte , sbyte , short , ushort , int , uint , long or ulong ".
    it may be correctly stated in grammar and implemented in compiler, but i think it's something like a little 'suprise' or 'inconsistent' in the grammar, on one hand it want to make developers to think byte, short, int as 'aliases' and 'interchangable', on the other hand, it make little exceptions like this without any good/real technical reasons,  i think it's an unessesary and confusing limitation, if ms remove this there will be no harm to the language/compiler but more natuaral and consistent to understand and remember.
    Monday, April 5, 2010 3:50 PM
  • This is exactly why the designers wanted to prohibit developers from defining their own ValueTypes by inheriting from them.  Consider the mess that occurs when you start overriding the base class methods.  Consider the mess that is created when you need to use 2 different libraries that each define their own Value Types, which are different from what you defined or need. 

    why ?? 'enum class' is just the keyword to define a managed enum in C++/CLI, like 'enum' in C#, its not a real 'class' at all.
    I'm just demostrating that a managed enumeration can be based on Int16 as well as 'short', there is no technical problem at all.

    So the limitation in C# is just a deliberate exception made in its grammar, with no real underlying reasons, right ?

    • Edited by TheCat666 Monday, April 5, 2010 5:18 PM
    Monday, April 5, 2010 3:59 PM
  • <So the limitation in C# is just a deliberate exception made in its grammar, with no real underlying reasons, right ? >

    I have already answered that question.  It is "by design" that Value Types are sealed.  It was done for several good reasons.  You just quoted me reciting some of them.  I agree with the compromise reached by the design decision to severely control and restrict how Value Types are used, defined, and inherited.


    Mark the best replies as answers. "Fooling computers since 1971."
    Monday, April 5, 2010 4:30 PM
    Moderator
  • in C++/CLI this compiles without problem (VS2008)

     

    public
     enum
     class
     States: Int16
    

    So what.

    Mark the best replies as answers. "Fooling computers since 1971."
    Monday, April 5, 2010 4:32 PM
    Moderator
  • <So the limitation in C# is just a deliberate exception made in its grammar, with no real underlying reasons, right ? >

    I have already answered that question.  It is "by design". and done for several good reasons.  You just quoted me reciting some of them.  I agree with the compromise reached by the design decision to severely control and restrict how Value Types are used, defined, and declared.


    Mark the best replies as answers. "Fooling computers since 1971."

    and .... in fact, an enum defined this way is 'NOT' changing its 'base class' or inheritance relationship at all, the ' : ' means different things here, 'underlying type' is NOT 'base type'

    internally, all enums are inherited directly from System.Enum, which looks like, well, sort of, a struct with a single field 'value__', and several static constants. and the ' : ' here defines the type of this single field, its nothing about defining our own ValueType or what, just changing the type of a simple member field.

    so this limitation means: you can define a member field as 'short' but not 'Int16', which makes no sense, and breaks the 'alias' and 'interchangable' concept.

    • Edited by TheCat666 Monday, April 5, 2010 6:05 PM
    Monday, April 5, 2010 5:29 PM
  • Yes it is.  The net result is that you are able to define a type that inherits from a sealed class, System.ValueType.  All System.Enum inherits from System.ValueType.  Ditto for a struct.

        enum Values : short
        {
            Droid,
            Druid
        }
    
    

    Instances of this type can be cast to and from Int16, but not Int32.

    Mark the best replies as answers. "Fooling computers since 1971."

    http://social.msdn.microsoft.com/Forums/en-US/netfxbcl/thread/4b6ecba3-77b5-4714-aa62-e9319d734c34

    Monday, April 5, 2010 5:34 PM
    Moderator
  • actually, the only reason i can imagine to enfore this limitation is, it's probably a little bit easier for compiler developers to implement, because 'int', 'short' is part of the language itself, the compiler knows what they are already, they cant be used for other purpose, and 'Int16' 'Int32' is part of the runtime, and can be defined as other types in code, so the compiler needs a little bit more parsing work and type info to determine if its a valid 'underlying type' for an enum.

    but from user's point of view its a little bit too strict, unnecessarily.

    Monday, April 5, 2010 6:12 PM
  • Accept the fact that it is not about to change.  Pros and cons were weighed, and the correct decisions was made.  It was done for the reasons that I have already stated.  To eliminate the chaos the results when developers are able to define and redefine their own Value Types.  Historically, this has been a horrific problem with C/C++ libraries.  Clash of the Types.

    Managed code did away with those problems by prohibiting you from inheriting Value Types.  The type is sealed  Inheritance from a type would mean that instance---not values---would get stored on the Managed Heap as a Reference Type; not even in a box.  Value types are supposed to be stored on the Stack as a Value Type .


    Mark the best replies as answers. "Fooling computers since 1971."
    Monday, April 5, 2010 6:33 PM
    Moderator
  • Accept the fact that it is not about to change.  Pros and cons were weighed, and the correct decisions was made.  It was done for the reasons that I have already stated.  To eliminate the chaos the results when developers are able to define and redefine their own Value Types.  Historically, this has been a horrific problem with C/C++ libraries.  Clash of the Types.

    Managed code did away with those problems by prohibiting you from inheriting Value Types.  The type is sealed  Inheritance from a type would mean that instance---not values---would get stored on the Managed Heap as a Reference Type; not even in a box.  Value types are supposed to be stored on the Stack as a Value Type .


    Mark the best replies as answers. "Fooling computers since 1971."


    I can accept the fact that its not going to change.

    but the reason you stated is NOT CORRECT. as Captain Kernel stated above, its NOT about inheriting at all, the ' : ' in enum and class declarations have totally different meanings.

    the 'underlying type' is just a type parameter for an internal member field, works exactly like Nullable<T>, where T defines the type of its value member field. the C# spec use the term 'underlying type' with enums and nullables. enums have more compiler magic and syntactic sugar to support it, and more limitations about what T can be, but technically, we should be allowed to use Int16 as the T here.

    Monday, April 5, 2010 6:56 PM
  • Okay, I was not clear enough.  When you use the colon followed by type name--no keywords used---that syntax is implied to be inheritance, unless of course the type name is an interface.  The compiler thinks you are trying to inherit a sealed class.  That is what I meant by you cannot inherit the .NET types.  The syntax itself implies inheritance.

    Notice how IntelliSense reacts and calls up type names for you to inherit as you type.

    I have also pointed out the advantages gained in platform independence by this behavior.  It also allows the C# source code to be independent of the .NET Framework.


    Mark the best replies as answers. "Fooling computers since 1971."
    Monday, April 5, 2010 7:07 PM
    Moderator
  • the 'underlying type' is just a type parameter for an internal member field, works exactly like Nullable<T>, where T defines the type of its value member field. the C# spec use the term 'underlying type' with enums and nullables. enums have more compiler magic and syntactic sugar to support it, and more limitations about what T can be, but technically, we should be allowed to use Int16 as the T here.

    I can't find any construct of C# where you can use a struct type and where you are restricted to a limited set of types.
    Tuesday, April 6, 2010 2:00 AM