An extension class that extends a flag based enumerated type with set/group theory type operations. See
FileAttributesExtender for a usage of this class.
public partial class EnumFlagsForm : Form
{
[Flags]
public enum EnumFlags
{
None = 0,
Emergency_Stop = 0x1,
Greasey = 0x2,
Spot_Spot = 0x4,
Doughnuts = 0x8,
Lift_Moving = 0x10,
Doors_Open = 0x20,
Forbidden = 0x40
}
//SourceTypes sourceTypes;
public static class EnumFlagsExtender
{
// Return lhs flags plus rhs flags
public static EnumFlags Union(this EnumFlags lhs, EnumFlags rhs)
{
return lhs | rhs;
}
// Return flags common to lhs and rhs
public static EnumFlags Intersection(this EnumFlags lhs, EnumFlags rhs)
{
return lhs & rhs;
}
// Return lhs flags minus rhs flags
public static EnumFlags Subtract(this EnumFlags lhs, EnumFlags rhs)
{
EnumFlags common = lhs & rhs;
int res = (int)lhs - (int)common;
return (EnumFlags)(res);
}
// Return true if lhs contains all the flags within rhs
public static bool Contains(this EnumFlags lhs, EnumFlags rhs)
{
EnumFlags common = lhs & rhs;
return (common == rhs);
}
// Return true if lhs contains one of the flags within rhs
public static bool ContainsOneOf(this EnumFlags lhs, EnumFlags rhs)
{
EnumFlags common = lhs & rhs;
return ((int)common > 0);
}
// NON-extension methods here
public static EnumFlags FromString(string source)
{
EnumFlags res = (EnumFlags)Enum.Parse(typeof(EnumFlags), source, true);
return res;
}
}
public void Test1()
{
EnumFlags test = EnumFlags.Lift_Moving |
EnumFlags.Doors_Open | EnumFlags.Doughnuts;
string str = test.ToString();
//str = str.Replace('_', ' ');
Debug.WriteLine(str);
EnumFlags newtest = EnumFlagsExtender.FromString(str);
Debug.Assert(newtest == test);
}
public void EnumFlagsSubtractTest()
{
EnumFlags test1 = EnumFlags.Lift_Moving | EnumFlags.Doors_Open |
EnumFlags.Doughnuts | EnumFlags.Emergency_Stop;
EnumFlags test2 = EnumFlags.Lift_Moving | EnumFlags.Forbidden |
EnumFlags.Emergency_Stop;
EnumFlags expected = EnumFlags.Doors_Open | EnumFlags.Doughnuts;
EnumFlags outcome = test1.Subtract(test2);
Debug.Assert(outcome == expected);
expected = EnumFlags.Doors_Open | EnumFlags.Doughnuts | EnumFlags.Greasey;
outcome = outcome.Union(EnumFlags.Greasey);
Debug.Assert(outcome == expected);
EnumFlags test3 = EnumFlags.Doughnuts | EnumFlags.Greasey;
bool res = outcome.Contains(test3);
Debug.Assert(res);
res = outcome.Contains(EnumFlags.Lift_Moving | EnumFlags.Forbidden);
Debug.Assert(!res);
}
public EnumFlagsForm()
{
InitializeComponent();
lbSourceTypes.Items.AddRange(
UnderscoresToSpaces(
Enum.GetNames(typeof(EnumFlags))));
OnSelectedValueChanged(this, null);
}
string[] UnderscoresToSpaces(string[] src)
{
return ReplaceInStrings('_', ' ', src);
}
string[] SpacesToUnderscores(string[] src)
{
return ReplaceInStrings('_', ' ', src);
}
string SpacesToUnderscores(string src)
{
return src.Replace(' ', '_');
}
string[] ReplaceInStrings(char oldchar, char newchar, params string[] src)
{
string[] res = new string[src.Length];
int ix = 0;
foreach (string targ in src)
{
res[ix++] = targ.Replace(oldchar, newchar);
}
return res;
}
private void OnSelectedValueChanged(object sender, EventArgs e)
{
EnumFlags test = EnumFlags.None;
foreach (string type in lbSourceTypes.SelectedItems)
{
test = EnumFlagsHelper.Add(test,
EnumFlagsHelper.FromString(SpacesToUnderscores(type)));
}
tbSelected.Text = test.ToString();
lblIsAudioAndVideo.Text = "WoopsTest() == " +
(EnumFlagsHelper.WoopsTest(test)).ToString();
}
private void butTest_Click(object sender, EventArgs e)
{
Test1();
EnumFlagsSubtractTest();
}
}
Here is a visual studio code snippet for the enum extender
<?xml version="1.0" encoding="utf-8"?>
<CodeSnippets xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">
<CodeSnippet Format="1.0.0">
<Header><Title>Flags Enum Extender pattern</Title>
<Description>Implement an extender for a 'Flags' type Enum. The extender adds set type methods to the enumertaion type</Description>
<Keywords>
<Keyword>Enum</Keyword>
</Keywords>
<Author>Roger Bovill</Author>
</Header>
<Snippet>
<Declarations>
<Literal Editable="true">
<ID>EnumName</ID>
<ToolTip>Name of the '[Flags]' based enumerated type</ToolTip>
<Default>MyEnumType</Default>
<Function></Function>
</Literal>
</Declarations>
<Code Language="CSharp">
<![CDATA[
#region $EnumName$Extender
public static class $EnumName$Extender
{
// Return lhs flags plus rhs flags
public static $EnumName$ Union(this $EnumName$ lhs, $EnumName$ rhs)
{
return lhs | rhs;
}
// Return flags common to lhs and rhs
public static $EnumName$ Intersection(this $EnumName$ lhs, $EnumName$ rhs)
{
return lhs & rhs;
}
// Return lhs flags minus rhs flags
public static $EnumName$ Subtract(this $EnumName$ lhs, $EnumName$ rhs)
{
$EnumName$ common = lhs & rhs;
int res = (int)lhs - (int)common;
return ($EnumName$)(res);
}
// Return true if lhs contains all the flags within rhs
public static bool Contains(this $EnumName$ lhs, $EnumName$ rhs)
{
$EnumName$ common = lhs & rhs;
return (common == rhs);
}
// Return true if lhs contains one of the flags within rhs
public static bool ContainsAnyOf(this $EnumName$ lhs, $EnumName$ rhs)
{
$EnumName$ common = lhs & rhs;
return ((int)common > 0);
}
// NON-extension methods here
public static $EnumName$ FromString(string source)
{
$EnumName$ res = ($EnumName$)Enum.Parse(typeof($EnumName$), source, true);
return res;
}
}
#endregion $EnumName$Extender
]]>
</Code>
</Snippet>
</CodeSnippet>
</CodeSnippets>
No comments:
Post a Comment