Disassembler

Artificial intelligence is no match for natural stupidity.
15října2011

C#: Bitwise Enum Extensions


Jednou jsem tak procházel StackOverflow a něco jsem hledal. Už ani nevím, co to bylo, ale místo toho jsem našel dotaz na bitwise operátory. Dotaz samotný byl poměrně nezajímavý a primitivní, ale jedna z odpovědí byla překrásná a velice elegantní. Jistý Hugoware tam totiž postnul svůj výtvor - rozšíření Enumu o blbuvzdorné bitwise operátory.

EnumerationExtensions


namespace Enum.Extensions {
    public static class EnumerationExtensions {
        public static bool Has<T>(this System.Enum type, T value) {
            try {
                return (((int)(object)type & (int)(object)value) == (int)(object)value);
            } 
            catch {
                return false;
            }
        }

        public static bool Is<T>(this System.Enum type, T value) {
            try {
                return (int)(object)type == (int)(object)value;
            }
            catch {
                return false;
            }    
        }

        public static T Add<T>(this System.Enum type, T value) {
            try {
                return (T)(object)(((int)(object)type | (int)(object)value));
            }
            catch(Exception ex) {
                throw new ArgumentException(
                    string.Format("Could not append value from enumerated type '{0}'.", typeof(T).Name), ex);
            }    
        }

        public static T Remove<T>(this System.Enum type, T value) {
            try {
                return (T)(object)(((int)(object)type & ~(int)(object)value));
            }
            catch (Exception ex) {
                throw new ArgumentException(
                    string.Format("Could not remove value from enumerated type '{0}'.", typeof(T).Name), ex);
            }  
        }
    }
}

Rozšíření se pak užívá následovně:

SomeType value = SomeType.Grapes;
bool isGrapes = value.Is(SomeType.Grapes); //true
bool hasGrapes = value.Has(SomeType.Grapes); //true

value = value.Add(SomeType.Oranges);
value = value.Add(SomeType.Apples);
value = value.Remove(SomeType.Grapes);

bool hasOranges = value.Has(SomeType.Oranges); //true
bool isApples = value.Is(SomeType.Apples); //false
bool hasGrapes = value.Has(SomeType.Grapes); //false

Na svém blogu později Hugoware publikoval i verzi 2.0 této elegantní vychytávky. Hezké a užitečné.