简体   繁体   中英

C# Use int constants vs Enums without cast

I have some int constants grouped in several Enum, like:

enum myEnum{ 
OBJECT_A = 10, OBJECT_B = 13 };

Now I have several functions which take this Enums and do something, like:

void myfunc(myEnum e)
{ .... }

In my code, I need to use myfunc in both these two ways:

myfunc(myEnum.OBJECT_A);
myfunc(13);

This gives an error because ints aren't casted to Enum implicitly.

What do you recommend as a best practice to do this preserving readability of the code?

An obvious solution is to use myfunc((myEnum)13); but this is boring because one needs to cast the int every time and the code gets heavy.

So far what I did is (avoiding enums at all):

using EChannelInt = System.Int32;

public static class EChannel
{
    public static readonly int CH_CONNECTION        = 10;
    public static readonly int CH_DATA              = 50;
}

public void doit(EChannelInt ch)
{ .... }

doit(EChannel.CH_DATA);
doit(10);

which works, but I don't like it very much because it seems like a "trick" or renaming thigs. What do you suggest? Perhaps "implicit operator" may be useful?

You can overload myFunc :

void myFunc(int i)
{
    myFunc((myEnum)i);
}

You can use type-safe-enum pattern and you can override the implicit cast operator.

public class EChannel
{
    public int Value {get; private set;};

    public static readonly EChannel CH_CONNECTION        = new EChannel(10);
    public static readonly EChannel CH_DATA              = new EChannel(50);

    private EChannel(int value)
    {
        Value = value;
    }

    public static implicit operator EChannel(int a)
    {
        EChannel eChannel = null;
        switch (a) // this need to be changed to something more light
        {
            case 10:
                eChannel = CH_CONNECTION;
                break;
            case 50:
                eChannel = CH_DATA;
                break;
            default:
                throw new Exception("Constant don't exists");
        }
        return eChannel;
    }
}

And you use it like this

public void doit(EChannel ch)
{ .... }

doit(EChannel.CH_DATA);
doit(10);

How about an overload?

void myfunc(int i)
{
    myfunc((myEnum)i);
}

(If you don't have control of the class, you can do it as an extension method .)

I would stick with the enumeration values as much as possible and only cast to int in a narrow scope when absolutely necessary (if at all).

However, if you insist on mixing integers and enumeration values then you should consider defining the enum members from the integers so that they are guaranteed to be consistent.

Example:

public static class EChannel
{
    public const int CH_CONNECTION = 10;
}

public enum myEnum
{
    CH_CONNECTION = EChannel.CH_CONNECTION
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM