0

C# is cool and will allow comparison of Enums and then convert to strings. I already got from SO some code to enumerate the individual items of an Enum (top method in class below). Then, in second method (that I wrote) I managed to convert to string when an enum matches a given value.

The third method, I would like some help with. Given a flag based enum where the given value is in fact many values AND'ed together, I want to atomise the values and convert to a List<string>. If I had C# 7.3 then I think limiting the <T> to an enum might help the compilation. Until then, how can achieve the goal of decomposing a flag enum into atomic values converted to strings.

public static class EnumUtil
{
    // JaredPar https://stackoverflow.com/questions/972307/can-you-loop-through-all-enum-values#answer-972323
    public static IEnumerable<T> GetValues<T>()
    {
        return Enum.GetValues(typeof(T)).Cast<T>();
    }

    // S Meaden
    public static string MatchFirst<T>  (T matchThis)
    {
        T[] values = (T[])EnumUtil.GetValues<T>();
        foreach (T val in values)
        {
            if (matchThis.Equals(val))
            {
                return val.ToString();
            }
        }
        return "";
    }

    // S Meaden
    // C# 7.3 https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/generics/constraints-on-type-parameters#enum-constraints
    public static List<string> MatchFlags<T> (T matchThis) where T : System.Enum
    {
        List<string> flags = new List<string>();

        T[] values = (T[])EnumUtil.GetValues<T>();

        long lMatchThis = (long)matchThis;
        foreach (T val in values)
        {
            long lVal = val;
            //if (lMatchThis & lVal)
            if (matchThis & val)
            {
                flags.Add(val.ToString());
            }
        }
        return flags;
    }
}

Can't get past C# 7.2.

enter image description here

S Meaden
  • 8,050
  • 3
  • 34
  • 65
  • Why don't you have 7.3? It is available right now... – Ron Beyer Aug 21 '18 at 20:12
  • No, it isn't the framework version, go to the build tab, select advanced, then select the language version. The framework version and language version are two different things. Make sure visual studio is up to date, it includes language support. I've been using it for over a month. – Ron Beyer Aug 21 '18 at 21:13
  • It isn't .NET core... [Here is the build settings](https://imgur.com/a/2l4660j) from a project I'm compiling against .NET Framework 4.6.2. This has nothing to do with .NET Core or the framework version, it is build settings inside Visual Studio and should show C# 7.3 if you have the latest version of VS2017 installed (15.7.4) – Ron Beyer Aug 21 '18 at 21:41
  • Ok, I got 7.3 now. I guess I have no excuses now. I'll try again to write the logic I need. Thanks @RonBeyer – S Meaden Aug 21 '18 at 23:21

1 Answers1

2

Use where T : struct and throw an ArgumentException if not a System.Enum:

public static List<string> MatchFlags<T> (T matchThis) where T : struct
{
    if (!(matchThis is System.Enum)) {
        throw new ArgumentException("Gotta be an enum");
    }
    //etc.
}

If you have a flags enum and you want to convert it into a List<string>, do something like this:

matchThis.ToString().Split(',').ToList();
S Meaden
  • 8,050
  • 3
  • 34
  • 65
Flydog57
  • 6,851
  • 2
  • 17
  • 18
  • Thanks. The flags enum is a numeric. It needs to be split out by looping through the enum's items and testing the logical AND'ing of them. – S Meaden Aug 21 '18 at 21:48
  • Ooops! My initial answer omitted the .ToString() call. If your flags enum looks like `public enum SomeEnum { yes = 1, no = 2, maybe = 4};` and you have a value like `var myEnum = SomeEnum.yes | SomeEnum.maybe;` then `myEnum.ToString()` will end up being `"yes,maybe"`, and that expression will be a list of strings containing "yes" and "maybe" – Flydog57 Aug 21 '18 at 21:51
  • No problem. I'm stuck writing that code about once every month or three because of our environment. I'm so looking forward to `where T : System.Enum` – Flydog57 Aug 21 '18 at 23:25
  • Is your enum marked `[Flags]`? The code in that posting and in the subsequent comment was taken from my little test program that works. The reason I missed the `.ToString()` call was a select/copy error. – Flydog57 Aug 21 '18 at 23:26
  • ah! Astonishing! – S Meaden Aug 21 '18 at 23:28
  • That flags enum .ToString trick is very handy. You can also parse (and TryParse) a string like that back into an enum (possibly ignoring case). It's very handy in config files. – Flydog57 Aug 21 '18 at 23:31
  • superb! Thanks very much. – S Meaden Aug 21 '18 at 23:31