0

It is very interesting to me why this code will not give an exception and 12356 will be output to the console? What is the meaning of this behavior enum?

enum Dummy { D1 = 123, D2 = 1234, D3 }
class Program
{
     static void Main(string[] args)
     {
          Dummy d = (Dummy)12356;
          Console.WriteLine((int)d);
          Console.ReadKey();
     }
}

Is this a bug or a feature?

Patrick Hofman
  • 153,850
  • 22
  • 249
  • 325
Mikhail
  • 57
  • 6
  • I don't think it's a duplicate. This question asks why casting a random integer to an enum is allowed, as opposed to whether it is possible. – GSerg Nov 23 '18 at 11:50
  • That topic does not answer my question, so it is not a duplicate. – Mikhail Nov 23 '18 at 11:54
  • I agree with GSerg, although I have an interest in this question getting reopened, so I won't vote myself. – Patrick Hofman Nov 23 '18 at 11:59
  • It is consistent with the way other casts work in C#. Like from int to byte and that int stores a negative value or 256 or more. Mental model is "I wrote this code intentionally, don't bother double-checking that I got it right". These kind of checks are quite expensive, especially so for an enum. The only exception is casts on objects, they have to be checked since not doing will cause nasty undebuggable memory corruption problems. – Hans Passant Nov 23 '18 at 12:08
  • The *direct* duplicate is probably not the *direct* answer. But that answer is itself a duplicate. The duplicate marked by Patrick Hofman probably contains the answer you're looking for: [Cast int to enum in C#](https://stackoverflow.com/questions/29482/cast-int-to-enum-in-c-sharp). See [atlaste's answer](https://stackoverflow.com/a/22830894/7444103) there (it could use an update, though). – Jimi Nov 23 '18 at 12:12
  • The answer by Michael in the duplicate is the answer to your question. It doesn't have to be the accepted answer. – Crowcoder Nov 24 '18 at 12:31

2 Answers2

2

Is this a bug or a feature?

A feature, although it might bring you in curious circumstances when the code doesn't work as expected.

You could for example combine enum values, for example:

enum Dummy { D1 = 1, D2 = 2, D3 = 4 }

Dummy v = Dummy.D1 | Dummy.D2;

The backing value here is 3.

You can check for either of the values like this:

bool isD1 = (v & Dummy.D1) == Dummy.D1;

You could check your enum for single value validness like this:

Dummy v = Dummy.D1;
bool isValid = Enum.IsDefined(typeof(Dummy), v);
Patrick Hofman
  • 153,850
  • 22
  • 249
  • 325
0

This is by design but discouraged, as specified in the documentation:

It's possible to assign any arbitrary integer value to meetingDay. For example, this line of code does not produce an error: meetingDay = (Day) 42. However, you should not do this because the implicit expectation is that an enum variable will only hold one of the values defined by the enum. To assign an arbitrary value to a variable of an enumeration type is to introduce a high risk for errors.

You can always check if a given value is defined for an enum type by using IsDefined:

Console.WriteLine(Enum.IsDefined(typeof(Dummy), 123)); //True
Console.WriteLine(Enum.IsDefined(typeof(Dummy), 123456)); //False
Konamiman
  • 49,681
  • 17
  • 108
  • 138