Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I convert an enum between (string, list of flags, enum with flags)?

Tags:

c#

enums

parsing

How do I convert from enums to strings and vice versa?

And taking the case that enums can contain multiple flags, how can I get a list of all the flags an enum contains?

like image 633
Ahmed Fwela Avatar asked Jul 16 '16 10:07

Ahmed Fwela


People also ask

How do I convert an enum to a string?

There are two ways to convert an Enum to String in Java, first by using the name() method of Enum which is an implicit method and available to all Enum, and second by using toString() method.

How do you flag an enum?

The "|=" operator actually adds a flag to the enum, so the enum now contains two flag bits. You can use "|=" to add bits, while & will test bits without setting them. And Bitwise AND returns a value with 1 in the targeted bit if both values contain the bit.

Can enum take string values?

Every enum has both a name() and a valueOf(String) method. The former returns the string name of the enum, and the latter gives the enum value whose name is the string.

What is the role of flag attribute in enum?

The [Flag] attribute is used when Enum represents a collection of multiple possible values rather than a single value. All the possible combination of values will come. The [Flags] attribute should be used whenever the enumerable represents a collection of possible values, rather than a single value.


1 Answers

Update 2

there is a library that implements most of the functionality you would need from enums, with better performance https://github.com/TylerBrinkley/Enums.NET


From Enum To String: [Enum Instance].ToString();

Example: using System.Windows.Input;

ModifierKeys mk = ModifierKeys.None | ModifierKeys.Alt | ModifierKeys.Shift | ModifierKeys.Control;
mk.Tostring();

returns:

Alt, Control, Shift Note: "None" flag got removed


From string to Enum:

Enum.TryParse([(string) value],out [store variable]);
OR
Enum.Parse(typeof([Enum Type]), [(string) value], [(bool) should ignore character case ?]);

Example: using System.Windows.Input;

// Way 1:
ModifierKeys outenum;
bool successful = Enum.TryParse("None,Alt,Control,Shift", out outenum);

Console.WriteLine($"Is Successful ? : {successful}, result : {outenum.ToString()}");

Result: Is Successful ? : True, result : Alt, Control, Shift

OR

// Way 2:
ModifierKeys outenum = (ModifierKeys)Enum.Parse(typeof(ModifierKeys), "None,Alt,Control,Shift", true);
Console.WriteLine(outenum.ToString());

Result: Alt, Control, Shift


From Enum Flags to List

Example:

        ModifierKeys mk = ModifierKeys.None | ModifierKeys.Alt | ModifierKeys.Shift | ModifierKeys.Control;
        List<ModifierKeys> mklist =
            mk
            .ToString() // Convert the enum to string
            .Split(new[] { "," } , StringSplitOptions.RemoveEmptyEntries) // Converts the string to Enumerable of string
            .Select(//converts each element of the list to an enum, and makes an Enumerable out of the newly-converted items
                strenum =>
                {
                    ModifierKeys outenum;
                    Enum.TryParse(strenum , out outenum);
                    return outenum;
                })
            .ToList(); // Creates a List from the Enumerable

Result: {ModifierKeys.Alt , ModifierKeys.Shift , ModifierKeys.Control}


From List of enum flags to enum

Example:

 ModifierKeys[] mk = {ModifierKeys.None, ModifierKeys.Alt, ModifierKeys.Control, ModifierKeys.Shift};
 ModifierKeys mkc = mk.Aggregate((prev, next) => prev | next);
 Console.WriteLine(mkc.ToString());

Result: Alt, Control, Shift


From List of string to enum

Example:

    string[] mk = {"None", "Alt", "Control", "Shift"};
    ModifierKeys mkc = mk.Select(x => {ModifierKeys outenum; Enum.TryParse(x, out outenum); return outenum;}).Aggregate((prev , next) => prev | next);
    Console.WriteLine(mkc.ToString());

Result: Alt, Control, Shift


General notes:

  • Using way 1 when converting from string to Enum is preferred, because if way 2 fails it throws an exception, but if way 1 fails it returns false
  • When separating enum flags while parsing enum string, use the , separator only
  • Having spaces between flags in enum string won't matter, so "None , Alt,Control, Shift" = "None,Alt,Control,Shift"

UPDATE 1 :

I wrote a simple Generic EnumConverter class that saves you time

public class EnumConverter<T> where T : struct, IConvertible, IFormattable
{
    private Type EnumType { get; set; }

    public Type UnderlyingType
    {
        get
        {
            return Enum.GetUnderlyingType(EnumType);
        }
    }
    public EnumConverter()
    {
        if (typeof(T).IsEnum)
            EnumType = typeof(T);
        else
            throw new ArgumentException("Provided type must be an enum");
    }
    public IEnumerable<T> ToFlagsList(T FromSingleEnum)
    {
        return FromSingleEnum.ToString()
        .Split(new[] { "," } , StringSplitOptions.RemoveEmptyEntries)
        .Select(
            strenum =>
            {
                T outenum = default(T);
                Enum.TryParse(strenum , true , out outenum);
                return outenum;
            });
    }
    public IEnumerable<T> ToFlagsList(IEnumerable<string> FromStringEnumList)
    {
        return FromStringEnumList
        .Select(
            strenum =>
            {
                T outenum = default(T);
                Enum.TryParse(strenum , true , out outenum);
                return outenum;
            });
    }

    public T ToEnum(string FromString)
    {
        T outenum = default(T);
        Enum.TryParse(FromString , true , out outenum);
        return outenum;
    }
    public T ToEnum(IEnumerable<T> FromListOfEnums)
    {
        var provider = new NumberFormatInfo();
        var intlist = FromListOfEnums.Select(x => x.ToInt32(provider));
        var aggregatedint = intlist.Aggregate((prev , next) => prev | next);
        return (T)Enum.ToObject(EnumType , aggregatedint);
    }
    public T ToEnum(IEnumerable<string> FromListOfString)
    {
        var enumlist = FromListOfString.Select(x =>
        {
            T outenum = default(T);
            Enum.TryParse(x , true , out outenum);
            return outenum;
        });
        return ToEnum(enumlist);
    }

    public string ToString(T FromEnum)
    {
        return FromEnum.ToString();
    }
    public string ToString(IEnumerable<T> FromFlagsList)
    {
        return ToString(ToEnum(FromFlagsList));
    }

    public object ToUnderlyingType(T FromeEnum)
    {
        return Convert.ChangeType(FromeEnum , UnderlyingType);
    }
}

Usage :

 EnumConverter<ModifierKeys> conv = new EnumConverter<ModifierKeys>();
 //conv.ToEnum
 //conv.ToFlagsList
 //conv.ToString
like image 126
Ahmed Fwela Avatar answered Oct 22 '22 19:10

Ahmed Fwela