Why does the C # compiler allow empty enums?

I accidentally determined an enumeration today that did not have values. For example, for example:

public enum MyConfusingEnum{} 

The compiler was very happy to let me determine that the code was successfully created.

Now I obviously cannot use this in the traditional sense, as the code ...

 var mySadCompiler = MyConfusingEnum; 

does not indicate meaning, but interestingly enough, what I was able to say.

 var myRoundTheHousesZeroState = Activator.CreateInstance<MyConfusingEnum>(); 

which, as I mentioned, is a value type of MyConfusingEnum with a value of 0;

My question is: why does the compiler allow an empty definition and are there any scripts where this might be useful?

+71
compiler-construction enums c #
May 21 '14 at 22:30
source share
5 answers

Firstly, you could make it much easier:

 MyConfusingEnum x1 = 0; MyConfusingEnum x2 = default(MyConfusingEnum); MyConfusingEnum x3 = new MyConfusingEnum(); MyConfusingEnum x4 = (MyConfusingEnum) 123; 

all of the above works just fine. (You may be surprised that the first one works; see the section on implicit enumeration conversions for details.)

My question is why does the compiler allow an empty definition

I'll start by answering a question with a question. Could you also give up the compiler?

 class C {} interface I {} struct S {} 

Why or why?

In order not to directly answer your question: "Why is the world not different from it?" questions are hard to answer. Instead of answering this unresolved question, I will answer the question "suppose that for empty listings a mistake was made in the design team, how would you answer this step?" This question is still controversial, but at least it is one that I can answer.

The question then becomes whether the value of this function is justified by its benefits.

In order to work in the language, it is necessary to take into account, design, indicate, verify, test, document and send to customers. This is a "make a mistake" function, so the error message must be recorded and translated into several dozen languages, as well as the documentation. The five minutes that it would take me to implement this function went over the many hours of work of many people who are paid quite a lot.

However, this is actually not a significant cost. opportunity cost is the corresponding value. Budgets are finite, functions are not free, and therefore any implemented function means that you need to cut off another function; What C # function would you like to shorten to get this function? The lost benefit of not being able to make a better function is opportunity costs.

I also note that your proposed feature has zero obvious benefit for everyone, which would make it a tough sale to the project committee. Perhaps there is an irresistible benefit that I do not see; if so, what is it?

Are there any scenarios where this might be useful?

No one comes to mind. "Giving up programs that are clearly not useful" is not the purpose of developing C #.

+91
May 22 '14 at 2:33
source share

You can specify any value of the base integer type (in my opinion, the default int ) for the enumeration - therefore (MyConfusingEnum)42 will now have this enumeration type.

I don’t think this is a good idea in general, but there may be times when the β€œenum” values ​​come from an external source, and the code just looks better with enum .

Example (assuming code encapsulates some "int-based state" in Enum:

 enum ExternalDeviceState {}; ExternalDeviceState GetState(){ ... return (ExternalDeviceState )intState;} bool IsDeviceStillOk(ExternalDeviceState currentState) { .... } 

The specification does allow empty enumeration:

14.1 Listing Declarations

The enum declaration declares a new enumeration type. An enum declaration begins with the enum keyword and defines the name, accessibility, base type, and enumeration members.

 enum-declaration: attributesopt enum-modifiersopt enum identifier enum-base(opt) enum-body ;(opt) enum-base: : integral-type enum-body: { enum-member-declarations(opt) } { enum-member-declarations , } 

Note that enum-member-declarations(opt) explicitly marked as an option where nothing is inside {} .

+17
May 21 '14 at 22:34
source share

Activator.CreateInstance<MyConfusingEnum>(); same as new MyConfusingEnum() . ( docs )

A call to the enumeration constructor gives you 0 as a value.

Due to the design, the enumeration can have any value that is valid for the type of support (usually int ), it should not be the value defined in the enumeration.

For the reason of this design decision, I can indicate this answer to a question entitled "Why is int casting not valid for the value of the NOT throw exception enumeration?"

@AlexeiLevenkov provided a specification that allows null enumeration, we can guess that for this it is justification that, since a support type value is supported, null enumeration is allowed.

+14
May 21 '14 at 22:44
source share

Are there any scenarios where this might be useful?

As already mentioned, you can assign to this enum any value that resolves the base type with a simple cast. That way, you can force type checking in situations where int can be confusing. For example:

 public enum Argb : int {} public void SetColor(Argb a) { .... 

or do you want to have some extension methods without cluping the int data type, with them

 public static Color GetColor(this Argb value) { return new Color( (int)value ); } public static void Deconstruct( this Argb color, out byte alpha, out byte red, out byte green, out byte blue ) { alpha = (byte)( (uint)color >> 24 ); red = (byte)( (uint)color >> 16 ); green = (byte)( (uint)color >> 8 ); blue = (byte)color; } 

and use it as

 var (alpha, red, green, blue) = color; 
+7
May 22 '14 at 9:14
source share

Are there any scenarios where this might be useful?

I experienced one in the Java world.

In the case of enumerations, you know all the possible values ​​at compile time .

However, there is a time before compilation, when you may not know all the values ​​(yet) or in which you simply do not intend to implement any values.

During the development of the API, I implemented an enumeration without any values ​​to include a link to it from other interfaces. I added the values ​​later.

+3
May 29 '14 at 13:45
source share



All Articles