1

I have two questions, one deriving from the other.

  1. I'm trying to parse an Enum that has the FlagsAttribute attribute to another enum which also has the same attribute. My attempt is in the code below. If someone has found an efficient way of doing this please let me know. As my current method involves iterating for all set flags and parsing one by one and then logically OR'ing them together.
  2. In attempting to solve this I got this error: The type 'Program.Test' cannot be used as type parameter 'T' in the generic type or method 'Program.Parse<T>(string, bool)'. There is no boxing conversion from 'Program.Test' to 'System.FlagsAttribute'. What I'm really looking for here is an explanation as to why. Obviously both enums have the Flags attribute which is shorthand for FlagsAttribute so shouldn't there already exist a conversion?

Also link for the lazy : DotNetFiddle

Code:

public static void Main()
{
    var q = Parse<TestType>((Test.ACT | Test.SAT_2016).ToString());
    Console.WriteLine(string.Format("Type: {0}\t Value: {1}", q.GetType(), q));

    // */

}

public static T Parse<T>(string value, bool ignoreCase = false)
    where T : FlagsAttribute , IComparable, IFormattable, IConvertible
{
    if (value.ToString().Contains(",")){
        var parts = value.ToString().Split(',');
        var results = new List<T> ();
        var final = default(T);

        foreach (var part in parts){
            try {
                final |= (T)Enum.Parse(typeof(T), part, ignoreCase) ;
            }catch (Exception e){
                Console.WriteLine("Got exception");
                /* Supressed */
            }
        }
        return final;

    }else{
        return (T) Enum.Parse(typeof(T), value.ToString(), ignoreCase);
    }
}
[Flags]
public enum Test{
    ACT = 32,
    SAT_2016 = 65536,
};
[Flags]
public enum TestType {
    ACT = 4,
    SAT_2016 = 39,
};
Mike Rinos
  • 43
  • 1
  • 9
  • How about this? https://stackoverflow.com/questions/30186261/the-type-cannot-be-used-as-type-parameter-t-in-the-generic-type-or-method-bas – panoskarajohn Nov 25 '19 at 16:32
  • Also you can try the where T : new() which loosens generic restrictions. I am not sure this is what you need though. – panoskarajohn Nov 25 '19 at 16:39
  • Also this? https://stackoverflow.com/questions/79126/create-generic-method-constraining-t-to-an-enum – panoskarajohn Nov 25 '19 at 16:41
  • You don't have to call `ToString` on `value` as it's already a `string`. Also instead of checking for the comma you can just use the code that splits the string as that will work even if there is no comma (it would return an array that contains just the original string). If not you don't catch the potential exception when parsing a value that doesn't contain a comma. – juharr Nov 25 '19 at 17:06

1 Answers1

1

Your enum has the [Flags] attribute; it doesn't inherit from FlagsAttribute - so just remove the T : FlagsAttribute constraint.

In C# 7.3 or above, you can just use the where T : Enum constraint directly; there is no way of expressing "has a specific attribute" in a generics constraint - you'd have to check that via reflection at runtime.

Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900
  • That takes care of the exception, and I guess it makes sense that it doesn't implement the `FlagsAttribute` class, but that still doesn't allow me to logically or together the results. Since I'm not on C# 7.3 I have replaced the FlagsAttribute with the struct which is what I initially was using. – Mike Rinos Nov 25 '19 at 17:23