Extension method for adding value to bit field (flags enum)

18,599

Solution 1

Not in any useful way. Enums are value types, so when making an extension method a copy of the enum will get passed in. This means you need to return it in order to make use of it

    public static class FlagExtensions
    {
        public static MyFlags Add(this MyFlags me, MyFlags toAdd)
        {
             return me | toAdd;
        }
    }

    flags = flags.Add(MyFlags.Coke); // not gaining much here

And the other problem is you can't make this generic in any meaningful way. You'd have to create one extension method per enum type.

EDIT:

You can pull off a decent approximation by reversing the roles of the enums:

public static class FlagsExtensions
{
    public static void AddTo(this MyFlags add, ref MyFlags addTo)
    {
         addTo = addTo | add;
    }
}


MyFlags.Coke.AddTo(ref flags);

Solution 2

I'm also working on Enum extension methods.

I tried to create add / remove generic methods for Enums, but I found it redundant.

To add you can just do:

MyFlags flags = MyFlags.Pepsi;
flags |= MyFlags.Coke;

To remove you can do:

MyFlags flags = MyFlags.Pepsi | MyFlags.Coke;
flags &= ~MyFlags.Coke;

Do not use XOR (^), it adds the flag if it does not exist.

flags ^= MyFlags.Coke; // Do not use!!!

Hope it helped. You can see more extension methods on: My blog

Solution 3

Not a solution, but if your aim is to reduce verbosity and increase readability, a fluent interface with extension methods could help at least partially:

[Flags]
public enum MyFlags
{
    None = 0,
    A    = 0x1,
    B    = 0x2,
}

public static class MyFlagsExt
{
    public static MyFlags A(this MyFlags myFlags)
    {
        return myFlags | MyFlags.A;
    }

    public static MyFlags B(this MyFlags myFlags)
    {
        return myFlags | MyFlags.B;
    }
}

...

var flags = MyFlags.A.B();
Share:
18,599
MsBao
Author by

MsBao

Updated on June 20, 2022

Comments

  • MsBao
    MsBao about 2 years

    Instead of doing this to add a value to flags enum variable:

    MyFlags flags = MyFlags.Pepsi;
    flags = flags | MyFlags.Coke;
    

    I'd like to create an extension method to make this possible:

    MyFlags flags = MyFlags.Pepsi;
    flags.Add(MyFlags.Coke);
    

    Possible? How do you do it?

  • MsBao
    MsBao about 13 years
    I can't have the first parameter passed by reference?
  • Matt Greer
    Matt Greer about 13 years
    Not in an extension method. You could create a standard utility method and do that though. You might be able to flip the method around have the one being added be the this parameter and the receiver be a ref parameter. MyFlags.Coke.AddTo(flags);
  • MsBao
    MsBao about 13 years
    Why can't you do it in an extension method?
  • Matt Greer
    Matt Greer about 13 years
    That's what the C# overlords decided :) I'm sure there are good technical reasons why not.
  • drzaus
    drzaus over 11 years
    XOR actually toggles the flag -- so like you said it adds it if it didn't exist, but it should also remove it if it did exist. A good reference (albeit refering to Javascript)
  • GoldBishop
    GoldBishop about 11 years
    Necro'ing Seems like this addition can be simplified by doing addTo |= add.
  • Suamere
    Suamere over 6 years
    Reducing verbosity shouldn't be anybody's aim in C#. It is compiled down to symbols, so file size of code doesn't matter. More Verbose ~= More Readable. On the same note, MyFlags.A.B() means nothing to me when I look at it. In order for me to understand this code, I have to understand the programmer (you) and the way your mind works. That isn't good for readability or maintainability. Also, nothing in this answer is an interface. So there is no fluid interface here, be that a contract or a UI. I can only agree with the first three words of your answer.
  • Amir Abiri
    Amir Abiri over 6 years
    There is no reason to downvote based on personal preference, just on how well or not the answer fits the question. Verbosity has nothing to do with file size. Experienced programmers know that too verbose code is harder to understand, as it reduces signal to noise ratio. If the OP wishes to reduce verbosity in this case, I trust his or her judgement. Also see here: softwareengineering.stackexchange.com/questions/141175/…
  • Suamere
    Suamere over 6 years
    1. The OP never said they want to reduce verbosity. 2. Nothing I said was personal preference. 3. That link you posted doesn't support your arguments as much as it says your answer is too cryptic. 4. I'd also point out that my comment said More Verbose About Equals More Readable. E.G.: Walk the line between lengthy names and cryptic names, exactly as the link you posted mentions. It isn't obvious that animal.Cat() adds the Cat flag to the Animal. And how would it remove the cat flag? Also, your single-letter example is confusing types.P().O().K().E().M().O().N()