The compile-able code worth a thousand words; Copy the
following code in your own project to see which technique of bitwise operations
on enumerations are best suitable for your needs.
using System.Diagnostics; using System; namespace EnumApp { public enum Planets { //Start with zero and increment by the power of 2 //Make sure you assign explicit values or you will get //weired results with bitwise operations //e.g 00001000 | 00010000 = 00011000 Undefined = 0, //00000000 Mercury = 1, //00000001 Venus = 2, //00000010 Earth = 4, //00000100 Mars = 8, //00001000 Jupiter = 16 //00010000 } //A static class which will hold the extension methods for //type System.Enum //This way all the enums you will create in your project //will have following extension methods. public static class EnumBitwiseExtension { //Look at method UseExtendedApproach in EnumBitwise class to see //how to use following methods. public static bool Contains(this Enum type, T value) { return (((int)(object)type & (int)(object)value) == (int)(object)value); } public static bool EqualTo (this Enum type, T value) { return (int)(object)type == (int)(object)value; } } public class EnumBitwise { //This method demonstrates the most simple technique //of using bitwise operations on enumerations //This technique of using bitwise operations can be //used with any version of .NET framework //Following technique requires more code to be written //but delivers the best performance. public void UseClassicApproach() { //Setting a value Planets plnt1 = Planets.Earth; //Setting multiple values Planets plnt2 = Planets.Earth | Planets.Jupiter | Planets.Mars; //Removing a value Planets plnt3 = plnt2 & ~Planets.Jupiter; bool isEarth = plnt1 == Planets.Earth; bool containsMars = (plnt1 & Planets.Mars) == Planets.Mars; bool containsEarthAndMars = (plnt3 & Planets.Earth) == Planets.Earth && (plnt3 & Planets.Mars) == Planets.Mars; } //This method demonstrates how to use extension methods //defined above for type Enum //This technique can be used with .NET 3.5 and higher public void UseExtendedApproach() { //Setting a value Planets plnt1 = Planets.Earth; //Setting multiple values Planets plnt2 = Planets.Earth | Planets.Jupiter | Planets.Mars; //Removing a value Planets plnt3 = plnt2 & ~Planets.Jupiter; bool isEarth = plnt1.EqualTo(Planets.Earth); bool containsMars = plnt2.Contains(Planets.Mars); bool containsEarthAndMars = plnt3.Contains(Planets.Earth | Planets.Mars); } //This method demonstrates how to use HasFlag //method which is being made available by .NET framework //This technique can be used with .NET 4.0 and higher public void UseNativeApproach() { //Setting a value Planets plnt1 = Planets.Earth; //Setting multiple values Planets plnt2 = Planets.Earth | Planets.Jupiter | Planets.Mars; //Removing a value Planets plnt3 = plnt2 & ~Planets.Jupiter; //Performance of HasFlag function has been made //little better in .NET 4.5 bool isEarth = plnt1.HasFlag(Planets.Earth); bool containsMars = plnt2.HasFlag(Planets.Mars); bool containsEarthAndMars = plnt3.HasFlag(Planets.Earth | Planets.Mars); } //Time to do some benchmarking public void TestPerformance() { string result = string.Empty; Stopwatch a = Stopwatch.StartNew(); for (int i = 0; i < 100000; i++) { UseExtendedApproach(); } a.Stop(); Stopwatch b = Stopwatch.StartNew(); for (int i = 0; i < 100000; i++) { UseNativeApproach(); } b.Stop(); Stopwatch c = Stopwatch.StartNew(); for (int i = 0; i < 100000; i++) { UseClassicApproach(); } c.Stop(); result = string.Format("UseClassicApproach: {0}ms; " + "UseExtendedApproach: {1}ms; " + "UseNativeApproach: {2}ms", c.ElapsedMilliseconds, a.ElapsedMilliseconds, b.ElapsedMilliseconds ); //I got following results on my computer //UseClassicApproach: 3ms; //UseExtendedApproach: 49ms; //UseNativeApproach: 220ms } } }
No comments:
Post a Comment
Your comments are highly appreciated!