Why can't I declare an enum inheriting from Byte, but can from a byte?

If I declare an enumeration like this ...

public enum MyEnum : byte { Val1, Val2 } 

... it works.

If I declare an enumeration like this ...

 public enum MyEnum : System.Byte { Val1, Val2 } 

... he does not work. Compiler Throw:

error CS1008: byte type, sbyte, short, ushort, int, uint, long or ulong expected

As a byte is an alias of the actual type, System.Byte , why can't I use the second declaration?

+27
c # compiler-errors
Feb 15 2018-11-15T00:
source share
6 answers

Well, this is according to the specification (Β§14.1). The grammar states that the product enum-declaration equals

 enum-declaration: attributes_opt enum-modifiers_opt enum identifier enum-base_opt enum-body ;_opt 

Where

enum-base is

 :integral-type 

and

 integral-type: sbyte byte short ushort int uint long ulong char 

As to why the specification is so, it is not clear.

Note that char is specified as a terminal for integral-type , but the specification explicitly states that

Note that char cannot be used as a base type.

By the way, I really think it's best to use aliases. I use only the .NET name instead of the C # keyword for these primitive types (and string ) when I want to call a static method. So

 Int32.TryParse 

instead

 int.TryParse. 

Otherwise, I say, for example, typeof(int) , not typeof(Int32) .

+26
Feb 15 2018-11-15T00:
source share

This raises a number of questions.

Why can't I declare an enum inheriting from Byte, but can from a byte?

As others have noted, this is what the specification says.

The entries of the language design committee do not justify this decision. June 2000 notes




Keywords for predefined types (e.g., int) and their corresponding type names (e.g., Int32) can be used interchangeably, but not completely. We discussed whether we want to make any changes to this area. We did not.

Here is a list of places where they are not interchangeable.

  • "int" can be used as the base type for enumerations; Int32 cannot.
  • Nickname ads cannot use keywords.



Some of my thoughts on this issue:

The first thing that comes to mind is that every time you give the user a choice, you give them the opportunity to write an error, and every time you give them the opportunity to write an error, you must make an error message for this. If we allowed an "X: byte enumeration", then we give a reasonable error message when the user accidentally deleted "using System;". We can avoid this confusion and all the costs of developing and testing a heuristic that reports errors by simply not allowing a choice in the first place.

The second thing that comes to mind is that the main type of enumeration is fundamentally connected with the enumeration mechanism, and not with its meaning. Therefore, it seems plausible that a sentence of a basic type should be limited to things that do not require semantic analysis; we know that the base type is one of eight possible types, so just let the user mechanically select one of these eight types uniquely.

The third thing that comes to mind is that error analysis can be performed during parsing rather than semantic analysis. The sooner the error is caught, the better.

UPDATE: I just asked one of the people who were in the room that day if there was something that I missed in my thoughts, and he said yes, they thought about it and decided that a complete type analysis is this is work for a development team, testing and maintenance, work that did not buy the user anything of value. (He also noted that they had similar arguments regarding System.Void: should it be legal to say β€œpublic static System.Void Main (string [] args)” for example? Again, they decided that this did not add value to users, but add potential ambiguity and work for the team.)




Why is char not a legal base type?

Again, what the spec says. Again, notes on language design since October 1999 do not help determine why:




Unsigned integral types can be used as base types for enumerations. The only integral type that cannot be used is char.




Again, we can guess. I assume the enumerations are for fancy numbers. Balls in practice are integers as part of the implementation, but logically they are not numbers, they are symbols. We want to be able to do operations with enumerations, such as adding, or-ing and and-ing flags, etc .; The specification makes it clear that these operations are performed as if they were performed according to the base type. The char type, which is not a logical number, does not define all the operators you may need. And finally, if you want a double-byte enumeration value, then you already have short and convenient ones at your disposal.




Related question from a letter on this subject:

A careful reading of the grammar specification indicates that β€œchar” is a grammatically legal base type, but a paragraph of explanatory text after the grammar indicates that β€œchar” is not a legal base type. Is the specification inconsistent?

Yes. I do not lose sleep over him. If this makes you feel better, imagine a grammar line that says

enum-base: integral type

reads instead

enum-base: integral type (but not char )

+29
Feb 15 '11 at 16:22
source share

The simplest answer is "as he indicated." (This is in section 14.1 of the C # 4 specification. Numbering may differ for other versions.)

The specification does not provide any specific reason for this 1, but it may be easier to describe the names of aliases of an integral type (which are all keywords) than to say that it can be any type that resolves (using aliases of another type, such as using ) directives into one of the defined sets.

Do you have a reason to use System.Byte instead?




1 In the annotated C # 4 specification, there is one annotation in this section ... but it was written by me and simply indicates that this is one of the few places in the specification where you really cannot replace aliases with regular type names. Therefore, it is not very useful for this question :)

+10
Feb 15 '11 at 15:09
source share

Here is the answer, at least in part, from MSDN :

Each type of enumeration has a base type, which can be any integral type except char. By default, the base enumeration type of Elements is int. To declare an enumeration of another integral type, such as a byte, use a colon after the identifier followed by a type, as shown in the following example.

Days of copying: byte {Sat = 1, Sun, Mon, Tue, Wed, Thu, Fri};

The approved enumeration types are byte, sbyte, short, ushort, int, uint, long, or ULONG.

+2
Feb 15 2018-11-15T00:
source share

For information only:

With the new Roslyn compiler, this code

 enum SomeEnum : System.Int32 { None, Some } 

therefore, now for base enumeration types not only aliases can be used, but also full types.

An example in dotnetfiddle where you can choose a compiler: https://dotnetfiddle.net/oXyAgV

+2
Feb 23 '16 at 7:56
source share

It seems that it does not accept names of real types, but only keywords of the language.

+1
Feb 15 2018-11-15T00:
source share



All Articles