2

I have an enum, suppose it is called sports:

enum Sports
{
  Baseball = 1,
  Basketball = 2,
  Football = 4,
  Hockey = 8,
  Soccer = 16,
  Tennis = 32,
  etc...
}

I would basically like to add an extension method that clears a mask bit like this:

Sports Mask = Sports.Baseball | Sports.Football | Sports.Tennis; //37
Mask.Clear(Sports.Baseball);
// Mask = Football | Tennis

This is the extension method I've come up with, it doesn't work. Clear doesn't affect Mask, the value remains 37. I'm not sure I can modify the this portion from within the extension method. Is there some other way to accomplish this?

public static void Clear<T>(this Enum value, T remove)
{
  Type type = value.GetType();
  object result;

  if (type.Equals(typeof(ulong)))
  {
    result = Convert.ToUInt64(value) & ~Convert.ToUInt64((object)remove);
  }
  else
  {
    result = Convert.ToInt64(value) & ~Convert.ToInt64((object)remove);
  }

  value = (Enum)Enum.Parse(type, result.ToString());
}
S2S2
  • 8,322
  • 5
  • 37
  • 65
Mark
  • 981
  • 2
  • 13
  • 25
  • As a side note, if you plan on displaying the enums via a string representation, it is a good idea to add the `[flags]` attribute to the enum definition. For a good explanation check out this answer: http://stackoverflow.com/questions/8447/enum-flags-attribute/8480#8480 – Jason Down Jan 17 '12 at 05:23
  • Thanks. I have the [Flags] tag in my real code, but I hacked this together quick, then when I was running my example I was like "why doesn't it display the actual values, instead of 37" then I was like "oh" I forgot [Flags]. – Mark Jan 17 '12 at 05:36

3 Answers3

3

Because enums are value types, so that you modified the parameter only. You can return the modified value and assign it to the original variable.

public static T Clear<T>(this Enum value, T remove) { ... }
mask = mask.Clear(Sports.Baseball);
//just like
//DateTime dt = DateTime.Now;
//dt = dt.AddHour(1);

And by the way, I don't think it worth an extension method here. Why not just simply use:

mask = mask & ~Sports.BaseBall;
mask = mask & ~anotherMask;

Your extension method is very inefficient because of (un)boxing.

Cheng Chen
  • 42,509
  • 16
  • 113
  • 174
  • In your opinion, is the extension method better or worse than just doing Mask &= ~Sports.Baseball; Thanks for the answer btw. Edit: You answered my question in the edit as I hadn't refreshed. Thanks. – Mark Jan 17 '12 at 05:28
1

Krzysztof Cwalina at MSDN Blogs explains how to clear Enum values using Flags attribute on enums at the below 2 links:

http://blogs.msdn.com/b/kcwalina/archive/2006/08/29/clearingflagenum.aspx

http://weblogs.asp.net/bhouse/archive/2006/08/29/Clearing-Enum-Flags.aspx

Sample:

[Flags]
public enum Foos {
    A = 1,
    B = 2,
    C = 4,
    D = 8,
    AB = A | B,
    CD = C | D,
    All = AB | CD
}

static class Program {
    static void Main() {
        Foos value = Foos.AB;
        Console.WriteLine(ClearFlag(value,Foos.A);
    }
    public static Foos ClearFlag(Foos value, Foos flag) {
       return value & ~flag;
    }
}
S2S2
  • 8,322
  • 5
  • 37
  • 65
0

You're asking to pass the instance to the extension method by reference. But you can't do this in C#.

Community
  • 1
  • 1
sq33G
  • 3,320
  • 1
  • 23
  • 38
  • Thanks, that more or less what I suspected but was wondering if there was a built-in way around this. – Mark Jan 17 '12 at 05:34