Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unable to implicitly convert value from enum even though the underlying type is specified

Tags:

c#

.net

enums

In the following code sample I define an enum and specify its underlying type as byte. I then attempt to assign to a byte value and switch on the enum's values but I get an error: Cannot implicitly convert type 'CmdlnFlags' to 'byte'. An explicit conversion exists (are you missing a cast?)

The code:

using System;

public enum CmdlnFlags: byte {
    ValA = (byte)'a',
    ValB = (byte)'b',
}

public class Sample {
    public static void Main() {
        byte switchByte = CmdlnFlags.ValB;
        switch (switchByte) {
            case CmdlnFlags.ValA: Console.WriteLine('A'); break;
            case CmdlnFlags.ValB: Console.WriteLine('B'); break;
        }
        Console.ReadKey();
    }
}

It's easy enough to fix, just cast to byte, but why do I have to cast if the underlying type is specified for the enum? What's the point of specifying an underlying type if you have to cast anyway?

If I cast, everything works. Example:

        byte switchByte = (byte)CmdlnFlags.ValB;
        switch (switchByte) {
            case (byte)CmdlnFlags.ValA: Console.WriteLine('A'); break;
            case (byte)CmdlnFlags.ValB: Console.WriteLine('B'); break;
        }
like image 502
Paul Sasik Avatar asked Apr 11 '11 18:04

Paul Sasik


2 Answers

You have to cast to make sure that's really what you mean to do. It's a type safety feature.

You should think of the enum as being a distinct type from its underlying type - and from other enums with the same underlying type. They're sufficiently different that if you want to use one as another, you need to cast.

It can occasionally be a pain, but ultimately it's a good thing.

Why are you casting before the switch anyway though? Just switch on the actual enum values:

CmdlnFlags switchFlag = CmdlnFlags.ValB;
switch (switchFlag) {
    case CmdlnFlags.ValA: Console.WriteLine('A'); break;
    case CmdlnFlags.ValB: Console.WriteLine('B'); break;
}

Here, you don't really want to treat the flag as a byte - you want to treat it as a flag and switch on it. So that's exactly what you should do.

like image 80
Jon Skeet Avatar answered Sep 29 '22 04:09

Jon Skeet


In most cases, such casts are unnecessary. Rather than use a variable of type byte to control the switch, just create a variable of type CmdlnFlags.

    CmdlnFlags switchValue = CmdlnFlags.ValB;
    switch (switchValue) {
         case CmdlnFlags.ValA: Console.WriteLine('A'); break;
         case CmdlnFlags.ValB: Console.WriteLine('B'); break;
     } 

The casts are required to encourage a correct program design. You will typically not want to use an enum as a numeric value.

like image 35
Jeffrey L Whitledge Avatar answered Sep 29 '22 03:09

Jeffrey L Whitledge