Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
334 views
in Technique[技术] by (71.8m points)

c# - Why can't I declare an enum inheriting from Byte but I can from byte?

If I declare an enum like this ...

public enum MyEnum : byte {
    Val1,
    Val2
}

... it's working.

If I declare an enum like this ...

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

... it's not working. The compiler throw :

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

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

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

There are a number of questions raised here.

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

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

The language design committee notes do not justify this decision. The notes from June of 2000 say


The keywords for the predefined types (e.g., int) and their corresponding type names (e.g., Int32) can mostly but not entirely be used interchangeably. We discussed whether we wanted to make any changes in this area. We didn’t.

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

  • "int" can be used as an underlying type for enums; Int32 can't.
  • Alias declarations can't use keywords.

Some musings of mine on the subject:

The first thing that comes to mind is that every time you give a user a choice, you give them an opportunity to write a bug, and every time you give them an opportunity to write a bug you have to make an error message for it. If we allowed "enum X : Byte" then we have give a sensible error message when the user has accidentally erased the "using System;". We can avoid that potential confusion and all the costs of developing and testing an error-reporting heuristic by simply not allowing the choice in the first place.

The second thing that comes to mind is that the underlying type of an enum is fundamentally about the mechanism of the enum, not its meaning. It therefore seems plausible that the underlying type clause should be limited to things that require no semantic analysis; we know that the underlying type is one of eight possible types, so let's just have the user mechanically choose from one of those eight types unambiguously.

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

UPDATE: I just asked one of the people who was in the room that day whether there was anything that I missed in my musings and he said that yeah, they thought about it and decided that doing the full type analysis was work for the development, test and maintenance team, work which bought the user nothing of value. (He also noted that they had similar arguments over System.Void; should it be legal to say "public static System.Void Main(string[] args)" for example? Again, they decided that this added no value for users but did add potential ambiguity and work for the team.)


Why is "char" not a legal underlying type?

Again, that's what the spec says. Again, the language design notes from October 1999 are no help in determining why:


The unsigned integral types may be used as the underlying types for enums. The only integral type that cannot be used is char.


Again, we can guess. My guess would be that enums are intended to be fancy numbers. Chars are in practice integers as an implementation detail, but logically they are not numbers, they are characters. We want to be able to do operations on enums like addition, "or-ing" and "and-ing" flags, and so on; the spec is clear that these operations are done as though they were being done on the underlying type. The char type, not logically being a number, does not define all the operators you might want. And finally, if you want a two-byte enum value then you already have short and ushort at your disposal.


A related question from an email about this question:

A careful reading of the grammar specification says that 'char' is grammatically a legal underlying type, but the paragraph of explanatory text after the grammar says that 'char' is not a legal underlying type. Is the spec inconsistent?

Yes. I'm not losing sleep over it. If it makes you feel better, imagine that the grammar line that says

enum-base : integral-type

instead reads

enum-base : integral-type (but not char)


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...