Values of an Enum can only be integers?

7

Studying C #, I came across a situation, I want to get a value ( string ) from the console. And then compares it with the value of an enum . For example:

[Serializable]
public enum Command
{
    Exit            = "/exit",
    SendMessage     = "/msg",
    WhoIs           = "/whois"
}

And then, I want to compare the value and perform the appropriate actions:

switch(cmd)
    case Command.Exit:
    /* executa ações necessárias */

But it's giving you trouble, because the cmd variable is a string and I'm comparing an enum . Is it possible to use enum for this? How to make? Do you have a better alternative?

    
asked by anonymous 26.06.2015 / 17:06

2 answers

7

enum is a set (list) of constant . Each enumeration has an integer type associated with it, except char , the default type is int . Allowed types are byte , sbyte , short , ushort , int , uint , long or ulong .

The type is assigned to the enumeration as follows:

public enum : long Command
{
}

The first value of the enumeration receives the value 0 , the value is then incremented by 1 and assigned to the next constant, the process is repeated for all constants.

Picking up your example

public enum Command
{
    Exit,
    SendMessage,
    WhoIs
}

Each constant receives the following values:

Exit = 0 , SendMessage = 1 and WhoIs = 2

Default values can be overridden using initializers :

public enum Command
{
    Exit = 1,
    SendMessage,
    WhoIs = 4
}

Initializers , in addition to assigning a value to the constant, initialize the sequence of values of the following constants:

Exit = 1 , SendMessage = 2 and WhoIs = 4

Having said that and answering your question the values of the constants of an enum can only be integer type.

However, by using Attributes , we can do what you want.

/ p>

First we write a class to represent this attribute, this class inherits from Attribute :

public class StringValueAttribute : Attribute
{
    //Propriedade que recebe a string que irá ser atribuída à constante
    public string StringValue { get; protected set; }

    //No construtor inicializa-se a propriedade
    public StringValueAttribute(string value)
    {
        StringValue = value;
    }
}  

To get the value of the attribute we refer to Reflection . To make things easier we'll create the code as an extension method.

public static class ExtensionMethods
{
    public static string GetStringValue(this Enum value)
    {
        var type = value.GetType();

        FieldInfo fieldInfo = type.GetField(value.ToString());

        var attributes = fieldInfo.GetCustomAttributes(
            typeof(StringValueAttribute), false) as StringValueAttribute[];

        var stringvalue = attributes != null && attributes.Length > 0 ? attributes[0].StringValue : value.ToString();
        return stringvalue;
    }
}

How to use

Attributes are first associated with elements of enum

public enum Command
{
    [StringValue("/exit")]
    Exit,
    [StringValue("/msg")]
    SendMessage,
    [StringValue("/whois")]
    WhoIs
}

Then, to get the string, the GetStringValue() method is used. You can not use switch so use else if :

if(cmd == Command.Exit.GetStringValue())
{ 
    ......
    ......         
}
else if(cmd == Command.SendMessage.GetStringValue())
{
    ......
    ......         
}
else if(cmd == Command.WhoIs.GetStringValue())
{
    ......
    ......         
}    
....
.....
Note:

The GetStringValue class was written / adapted using the existing information in net . Unfortunately I do not remember where.

    
26.06.2015 / 18:25
4

According to documentation the only types supported by Enum are:

byte , sbyte , short , ushort , int , uint , long and ulong

I do not use a lot of C #, but in other programming languages, if I'm not mistaken, the use of Enum would be similar to several numeric constants with a namespace (just an explanation for understanding, not really) with numerical values but represented by "texts", such as the Exit you created.

The idea is to receive "numbers" that will be compared to the ENUM structure. There may be more uses for this, but the basic use is to always use the ENUM structure to guide yourself, not forgetting the meaning of that number, for example:

enviaSinal(Command.Exit);

This imaginary method will have switch that will compare the submitted command.

Now if what you want is to use "arguments" passed in a command line in your software, you can use a vector, it would look something like:

IDictionary<string, string> Commands = new Dictionary<string, string>();
dict["Exit"]        = "/exit";
dict["SendMessage"] = "/msg";
dict["WhoIs"]       = "/whois";

You can also create a class with static variables (I really do not know if this is the best way):

class Commands
{
    static readonly string Exit        = "/exit";
    static readonly string SendMessage = "/msg";
    static readonly string WhoIs       = "/whois";
}

Note that the variables are read-only.

    
26.06.2015 / 17:23