@@ -42,47 +42,38 @@ <h4><a href="/archive">March 05, 2008</a>
4242typesafe, but then I don’t think that’s the problem < a href ="http://blogs.msdn.com/brada/ "> Abrams</ a > and company were
4343trying to solve anyway.</ p >
4444< p > Here’s an example one:</ p >
45- < div class ="highlight ">
46- < pre > < code class ="language-csharp " data-lang ="csharp "> < span class ="p "> [</ span > < span class ="a "> Flags</ span > < span class ="p "> ]</ span >
45+ < pre class ="highlight language-csharp "> < span class ="p "> [</ span > < span class ="a "> Flags</ span > < span class ="p "> ]</ span >
4746< span class ="k "> public</ span > < span class ="k "> enum</ span > < span class ="t "> Fruits</ span >
4847< span class ="p "> {</ span >
4948 < span class ="i "> Apple</ span > < span class ="o "> =</ span > < span class ="n "> 1</ span > < span class ="p "> ,</ span >
5049 < span class ="i "> Banana</ span > < span class ="o "> =</ span > < span class ="n "> 2</ span > < span class ="p "> ,</ span >
5150 < span class ="i "> Cherry</ span > < span class ="o "> =</ span > < span class ="n "> 4</ span > < span class ="p "> ,</ span >
5251 < span class ="i "> Date</ span > < span class ="o "> =</ span > < span class ="n "> 8</ span > < span class ="p "> ,</ span >
5352 < span class ="i "> Eggplant</ span > < span class ="o "> =</ span > < span class ="n "> 16</ span >
54- < span class ="p "> }</ span > </ code > </ pre >
55- </ div >
53+ < span class ="p "> }</ span > </ pre >
5654< p > Nice, clean syntax. The way they solved C++’s name collision issues with enum
5755values is genius: < code > Fruits.Apple</ code > . Clearly these guys are using the old noggin.</ p >
5856< h2 > The annoying bit (argh, a pun)</ h2 >
5957< p > The one thing that < em > does</ em > annoy me about flag enums is the syntax to see if a
6058given flag (or set of flags) is set:</ p >
61- < div class ="highlight ">
62- < pre > < code class ="language-csharp " data-lang ="csharp "> < span class ="k "> if</ span > < span class ="p "> ((</ span > < span class ="i "> myFruit</ span > < span class ="o "> &</ span > < span class ="i "> Fruits</ span > < span class ="p "> .</ span > < span class ="i "> Date</ span > < span class ="p "> )</ span > < span class ="o "> ==</ span > < span class ="i "> Fruits</ span > < span class ="p "> .</ span > < span class ="i "> Date</ span > < span class ="p "> )</ span > </ code > </ pre >
63- </ div >
59+ < pre class ="highlight language-csharp "> < span class ="k "> if</ span > < span class ="p "> ((</ span > < span class ="i "> myFruit</ span > < span class ="o "> &</ span > < span class ="i "> Fruits</ span > < span class ="p "> .</ span > < span class ="i "> Date</ span > < span class ="p "> )</ span > < span class ="o "> ==</ span > < span class ="i "> Fruits</ span > < span class ="p "> .</ span > < span class ="i "> Date</ span > < span class ="p "> )</ span > </ pre >
6460< p > I’m not afraid of bitwise operators, but there’s some serious lameness in
6561here. Needing to specify the explicit < code > ==</ code > for type safety and having to use
6662the parenthesis because the operator precedence puts < code > ==</ code > before < code > &</ code > first?
6763Gross.</ p >
6864< h2 > For every nail there is a hammer</ h2 >
6965< p > Behold the solution:</ p >
70- < div class ="highlight ">
71- < pre > < code class ="language-csharp " data-lang ="csharp "> < span class ="k "> public</ span > < span class ="k "> static</ span > < span class ="k "> class</ span > < span class ="t "> FruitsExtensions</ span >
66+ < pre class ="highlight language-csharp "> < span class ="k "> public</ span > < span class ="k "> static</ span > < span class ="k "> class</ span > < span class ="t "> FruitsExtensions</ span >
7267< span class ="p "> {</ span >
7368 < span class ="k "> public</ span > < span class ="k "> static</ span > < span class ="t "> bool</ span > < span class ="i "> IsSet</ span > < span class ="p "> (</ span > < span class ="k "> this</ span > < span class ="t "> Fruits</ span > < span class ="i "> fruits</ span > < span class ="p "> ,</ span > < span class ="t "> Fruits</ span > < span class ="i "> flags</ span > < span class ="p "> )</ span >
7469 < span class ="p "> {</ span >
7570 < span class ="k "> return</ span > < span class ="p "> (</ span > < span class ="i "> fruits</ span > < span class ="o "> &</ span > < span class ="i "> flags</ span > < span class ="p "> )</ span > < span class ="o "> ==</ span > < span class ="i "> flags</ span > < span class ="p "> ;</ span >
7671 < span class ="p "> }</ span >
77- < span class ="p "> }</ span > </ code > </ pre >
78- </ div >
72+ < span class ="p "> }</ span > </ pre >
7973< p > With that, you can just do:</ p >
80- < div class ="highlight ">
81- < pre > < code class ="language-csharp " data-lang ="csharp "> < span class ="k "> if</ span > < span class ="p "> (</ span > < span class ="i "> myFruit</ span > < span class ="p "> .</ span > < span class ="i "> IsSet</ span > < span class ="p "> (</ span > < span class ="i "> Fruits</ span > < span class ="p "> .</ span > < span class ="i "> Date</ span > < span class ="p "> ))</ span > </ code > </ pre >
82- </ div >
74+ < pre class ="highlight language-csharp "> < span class ="k "> if</ span > < span class ="p "> (</ span > < span class ="i "> myFruit</ span > < span class ="p "> .</ span > < span class ="i "> IsSet</ span > < span class ="p "> (</ span > < span class ="i "> Fruits</ span > < span class ="p "> .</ span > < span class ="i "> Date</ span > < span class ="p "> ))</ span > </ pre >
8375< p > Much nicer. For kicks, here’s some other useful methods:</ p >
84- < div class ="highlight ">
85- < pre > < code class ="language-csharp " data-lang ="csharp "> < span class ="k "> public</ span > < span class ="k "> static</ span > < span class ="k "> class</ span > < span class ="t "> FruitsExtensions</ span >
76+ < pre class ="highlight language-csharp "> < span class ="k "> public</ span > < span class ="k "> static</ span > < span class ="k "> class</ span > < span class ="t "> FruitsExtensions</ span >
8677< span class ="p "> {</ span >
8778 < span class ="k "> public</ span > < span class ="k "> static</ span > < span class ="t "> bool</ span > < span class ="i "> IsSet</ span > < span class ="p "> (</ span > < span class ="k "> this</ span > < span class ="t "> Fruits</ span > < span class ="i "> fruits</ span > < span class ="p "> ,</ span > < span class ="t "> Fruits</ span > < span class ="i "> flags</ span > < span class ="p "> )</ span >
8879 < span class ="p "> {</ span >
@@ -103,27 +94,23 @@ <h2>For every nail there is a hammer</h2>
10394 < span class ="p "> {</ span >
10495 < span class ="k "> return</ span > < span class ="i "> fruits</ span > < span class ="o "> &</ span > < span class ="p "> (</ span > < span class ="o "> ~</ span > < span class ="i "> flags</ span > < span class ="p "> );</ span >
10596 < span class ="p "> }</ span >
106- < span class ="p "> }</ span > </ code > </ pre >
107- </ div >
97+ < span class ="p "> }</ span > </ pre >
10898< p > Useful, no?</ p >
10999< h2 > Why solve one when you can solve < em > n</ em > ?</ h2 >
110100< p > So, if you’re like me and < a href ="https://web.archive.org/web/20120423104722/http://devlicious.com/blogs/christopher_bennage/archive/2007/09/13/my-new-little-friend-enum-lt-t-gt.aspx "> this guy</ a > , right now you’re thinking, “This
111101just fixes one enum. Can I solve it for all enums?” Ideally, you’d do something
112102like:</ p >
113- < div class ="highlight ">
114- < pre > < code class ="language-csharp " data-lang ="csharp "> < span class ="k "> public</ span > < span class ="k "> static</ span > < span class ="k "> class</ span > < span class ="t "> EnumExtensions</ span >
103+ < pre class ="highlight language-csharp "> < span class ="k "> public</ span > < span class ="k "> static</ span > < span class ="k "> class</ span > < span class ="t "> EnumExtensions</ span >
115104< span class ="p "> {</ span >
116105 < span class ="k "> public</ span > < span class ="k "> static</ span > < span class ="t "> bool</ span > < span class ="t "> IsSet</ span > < span class ="o "> <</ span > < span class ="t "> T</ span > < span class ="o "> ></ span > < span class ="p "> (</ span > < span class ="k "> this</ span > < span class ="t "> T</ span > < span class ="i "> value</ span > < span class ="p "> ,</ span > < span class ="t "> T</ span > < span class ="i "> flags</ span > < span class ="p "> )</ span > < span class ="k "> where</ span > < span class ="t "> T</ span > < span class ="p "> :</ span > < span class ="t "> Enum</ span >
117106 < span class ="p "> {</ span >
118107 < span class ="k "> return</ span > < span class ="p "> (</ span > < span class ="i "> value</ span > < span class ="o "> &</ span > < span class ="i "> flags</ span > < span class ="p "> )</ span > < span class ="o "> ==</ span > < span class ="i "> flags</ span > < span class ="p "> ;</ span >
119108 < span class ="p "> }</ span >
120- < span class ="p "> }</ span > </ code > </ pre >
121- </ div >
109+ < span class ="p "> }</ span > </ pre >
122110< p > Unfortunately, that doesn’t fly. You can’t use < code > Enum</ code > as a constraint.
123111Likewise, there’s no way to require a typeparam to implement an operator (like
124112< code > &</ code > above). You < em > can</ em > implement a generic solution for this:</ p >
125- < div class ="highlight ">
126- < pre > < code class ="language-csharp " data-lang ="csharp "> < span class ="k "> public</ span > < span class ="k "> static</ span > < span class ="k "> class</ span > < span class ="t "> EnumExtensions</ span >
113+ < pre class ="highlight language-csharp "> < span class ="k "> public</ span > < span class ="k "> static</ span > < span class ="k "> class</ span > < span class ="t "> EnumExtensions</ span >
127114< span class ="p "> {</ span >
128115 < span class ="k "> public</ span > < span class ="k "> static</ span > < span class ="t "> bool</ span > < span class ="t "> IsSet</ span > < span class ="o "> <</ span > < span class ="t "> T</ span > < span class ="o "> ></ span > < span class ="p "> (</ span > < span class ="k "> this</ span > < span class ="t "> T</ span > < span class ="i "> value</ span > < span class ="p "> ,</ span > < span class ="t "> T</ span > < span class ="i "> flags</ span > < span class ="p "> )</ span >
129116 < span class ="k "> where</ span > < span class ="t "> T</ span > < span class ="p "> :</ span > < span class ="t "> struct</ span >
@@ -188,8 +175,7 @@ <h2>Why solve one when you can solve <em>n</em>?</h2>
188175 < span class ="p "> {</ span >
189176 < span class ="k "> return</ span > < span class ="i "> op</ span > < span class ="p "> ((</ span > < span class ="t "> T</ span > < span class ="p "> )</ span > < span class ="i "> value</ span > < span class ="p "> ,</ span > < span class ="p "> (</ span > < span class ="t "> T</ span > < span class ="p "> )</ span > < span class ="i "> flags</ span > < span class ="p "> );</ span >
190177 < span class ="p "> }</ span >
191- < span class ="p "> }</ span > </ code > </ pre >
192- </ div >
178+ < span class ="p "> }</ span > </ pre >
193179< p > …but, yeah, it’s not exactly fun using reflection for this.</ p >
194180 < div class ="comments ">
195181 < div id ="disqus_thread "> </ div >
0 commit comments