14

Given the code below:

static void Main()
{
    Console.WriteLine(typeof(MyEnum).BaseType.FullName);
}

enum MyEnum : ushort
{
    One = 1,
    Two = 2
}

It outputs System.Enum, which means the colon here has nothing to do with inheritance, and it just specifies the basic type of the enum, am I right?

But if I change my code as follows:

enum MyEnum : UInt16
{
    One = 1,
    Two = 2
}

I would get a compilation error. Why? Aren't UInt16 and ushort the same?

dtb
  • 213,145
  • 36
  • 401
  • 431
ojlovecd
  • 4,812
  • 1
  • 20
  • 22
  • Wouldn't have thought to try this, but an interesting observation nonetheless. – Marc L. Oct 28 '11 at 04:15
  • Someone (not the OP) edited this post and changed the last question from "Aren't UInt16 and int the same?". are you sure the OP didn't really mean what they asked? – Bradley Uffner Oct 28 '11 at 04:16
  • 3
    http://stackoverflow.com/questions/1813408/c-sharp-int-int32-and-enums or http://stackoverflow.com/questions/3774650/enum-members-of-int32-type or http://stackoverflow.com/questions/62503/c-int-or-int32-should-i-care/62800#62800 or http://stackoverflow.com/questions/757684/enum-inheritance –  Oct 28 '11 at 04:25
  • @BradleyUffner I made a mistake. I was planning to ask "Aren't UInt16 and ushort the same?" – ojlovecd Oct 28 '11 at 04:26
  • @BradleyUffner: Considering that the two code snippets used `ushort` and `System.UInt16`, it's clear those are the two being compared. – Ben Voigt Oct 28 '11 at 04:28
  • @CodeCanvas Thanks. I should have noticed that there were questions similar with it asked before. – ojlovecd Oct 28 '11 at 04:32
  • Enums can now use UInt16 as the base type. – Gavin Williams Feb 23 '19 at 01:41

5 Answers5

13

You are correct that reflection doesn't report that an enum inherits the base type, which the specification calls the "underlying type". You can find it using Enum.GetUnderlyingType instead.

The type named by ushort and System.UInt16 are precisely the same.

However, the syntax of enum does not call for a type. Instead it calls for one of a limited set of keywords, which control the underlying type. While System.UInt16 is a valid underlying type, it is not one of the keywords which the C# grammar permits to appear in that location.

Quoting the grammar:

enum-declaration:

attributesopt enum-modifiersopt enum identifier enum-baseopt enum-body ;opt

enum-base:

: integral-type

integral-type:

sbyte

byte

short

ushort

int

uint

long

ulong

char

Ben Voigt
  • 277,958
  • 43
  • 419
  • 720
5

Because the valid types for an enum are explicitly specified to be the integral types (except char).

The approved types for an enum are byte, sbyte, short, ushort, int, uint, long, or ulong.

http://msdn.microsoft.com/en-us/library/sbbt4032.aspx

One would expect the UInt16 to be equivalent to a ushort given the documentation for built in types:

The C# type keywords and their aliases are interchangeable. For example, you can declare an integer variable by using either of the following declarations...

http://msdn.microsoft.com/en-us/library/ya5y69ds.aspx

Edit: I had messed around with this answer a few times not quite grasping the correct answer. @BenVoight is correct. The accepted list are the integral types (other than char) The System.UInt16 is exactly the same type as ushort, but it is not an integral type identifier (merely a struct type) as specified by the grammar.

Kevin Stricker
  • 17,178
  • 5
  • 45
  • 71
  • 2
    No, it's because the grammar doesn't allow a type identifier to appear there. The only allowed production is *integral-type*, the choices for which are keywords. – Ben Voigt Oct 28 '11 at 04:16
  • Thanks, I knew I was contradicting myself there :/ Edited/credit given where due. – Kevin Stricker Oct 28 '11 at 04:23
4

That's compiler error CS1008, and it pretty much provides the answer. The approved types for an enum:

The approved types for an enum are byte, sbyte, short, ushort, int, uint, long, or ulong.

Jon
  • 428,835
  • 81
  • 738
  • 806
1

The first part of your question is answered by others, but no one has addressed the 2nd part yet. Someone other than the OP has since edited the 2nd question, my answer may no longer apply

UInt16 and UInt are not the same, UInt16 is an unsigned 16 bit integer, UInt is an unsigned 32 bit integer. They vary quite a bit in their maximum value.

Just for completeness, I'm including the answer to the. first question also:

The approved types for an enum are byte, sbyte, short, ushort, int, uint, long, or ulong.

Bradley Uffner
  • 16,641
  • 3
  • 39
  • 76
1

As for why?

My guess is CLS compliance.

leppie
  • 115,091
  • 17
  • 196
  • 297