2

I am refactoring some code for several enum collections that support the [Flags] attribute.

I am trying to come up with a generic class that allows for common methods (adding, removing and checking enums exist in the collection etc).

I began with this code:

public class EnumFlags<T>
{
    protected T collection;

    public void Add(T value)
    {
        this.collection = this.collection | value;
    }
}

However, I cannot use the | operator on type T. I cannot add a constraint for T to be an enum (where T : Enum is not allowed).

Any ideas to approaching this problem?

Class Skeleton
  • 2,913
  • 6
  • 31
  • 51
  • 3
    See my [Unconstrained Melody](https://code.google.com/p/unconstrained-melody) project - in this case, you'd want `Flags.Or`. (Also available as a nuget package - https://www.nuget.org/packages/UnconstrainedMelody/) – Jon Skeet Dec 17 '14 at 14:31
  • 1
    @Jodrell - yes, now corrected. – Class Skeleton Dec 17 '14 at 14:33
  • see here http://stackoverflow.com/a/79903/659190 – Jodrell Dec 17 '14 at 14:36
  • This seems like a sin to me and there must be a better way so I'm not going to answer with it, but this works: `this.collection = (T)(object)((int)(object)this.collection | (int)(object)value);` – David Sherret Dec 17 '14 at 14:44
  • @DavidSherret That is one of C#s dark secrets, if you have a cast the compiler won't accept you can always use the black magic of casting to an object as a go between. – Zache Dec 17 '14 at 15:22
  • 1
    @Jodrell @abatishchev I don't think this question is a duplicate of the referenced question. The main problem is the line `this.collection = this.collection | value;` and adding the constraint `where T : struct, IConvertible` doesn't solve that problem. Maybe there's something in those answers that you could reference specifically that solves this issue? If not, I think this question should be reopened. – David Sherret Dec 18 '14 at 03:08
  • I will have to spend some more time on a possible solution. Jon Skeet's project looks promising but may need to adapt it. As for the marked duplicate - I am struggling to use generics for the operators (and `HasFlag` method). I had one hack where I was using `Convert.ToInt64` but basically lost the generic completely. Also, I am unsure how to convert this int back to the Enum. Not sure that was the best approach as I was casting throughout. – Class Skeleton Dec 18 '14 at 08:02
  • For anyone still wondering, here is a working implementation: https://www.codeproject.com/Articles/133407/Using-a-Generic-Type-to-Simplify-Flags-Enumeration They solved it like this: int flag = Convert.ToInt32(value); _register = (_register | flag); return this.State; – Leo Hilbert May 27 '22 at 08:52

0 Answers0