<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Cameron McKay &#187; Dnum</title>
	<atom:link href="http://cdmckay.org/blog/category/dnum/feed/" rel="self" type="application/rss+xml" />
	<link>http://cdmckay.org/blog</link>
	<description>Programming, Politics and Game Design</description>
	<lastBuildDate>Thu, 09 Sep 2010 06:34:36 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Inconsistencies in the .NET Enum class</title>
		<link>http://cdmckay.org/blog/2009/09/14/inconsistencies-in-the-net-enum-class/</link>
		<comments>http://cdmckay.org/blog/2009/09/14/inconsistencies-in-the-net-enum-class/#comments</comments>
		<pubDate>Mon, 14 Sep 2009 05:59:44 +0000</pubDate>
		<dc:creator>cdmckay</dc:creator>
				<category><![CDATA[Dnum]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[.net]]></category>
		<category><![CDATA[c#]]></category>
		<category><![CDATA[enum]]></category>

		<guid isPermaLink="false">http://couchware.ca/blogs/cam/?p=948</guid>
		<description><![CDATA[During a recent project of mine, I had to do a lot of enum manipulation using the .NET Enum class and I have to say I wasn&#8217;t impressed.  Besides the shortcoming of it not being a generic class (and thus not being especially type-safe), Enum also has some strange inconsistencies in terms of how [...]]]></description>
			<content:encoded><![CDATA[<p>During a recent project of mine, I had to do a lot of enum manipulation using the .NET Enum class and I have to say I wasn&#8217;t impressed.  Besides the shortcoming of it not being a generic class (and thus not being especially type-safe), Enum also has some strange inconsistencies in terms of how it handles matched integral types.</p>
<p><span id="more-948"></span></p>
<h3>GetName</h3>
<p>Why does <code><a href="http://msdn.microsoft.com/en-us/library/system.enum.getname.aspx">GetName</a></code> return null for any integral type you pass it except those that correspond to a constant?</p>
<p>For example, this is completely valid:</p>

<div class="wp_syntax"><div class="code"><pre class="csharp" style="font-family:Consolas, monospace;"><span style="color: #FF0000;">enum</span> Fruit <span style="color: #008000;">:</span> <span style="color: #FF0000;">byte</span> <span style="color: #000000;">&#123;</span> Apple, Orange, Cumquat <span style="color: #000000;">&#125;</span><span style="color: #008000;">;</span>
var fruit <span style="color: #008000;">=</span> <span style="color: #FF0000;">Enum</span>.<span style="color: #0000FF;">GetName</span><span style="color: #000000;">&#40;</span> <span style="color: #008000;">typeof</span><span style="color: #000000;">&#40;</span>Fruit<span style="color: #000000;">&#41;</span>, <span style="color: #FF0000;">ulong</span>.<span style="color: #0000FF;">MaxValue</span> <span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
<span style="color: #008080; font-style: italic;">// fruit now equals null</span></pre></div></div>

<p>In every other case in the Enum class where you pass an integral value outside the range of the underlying type, you get an exception.  Except here.</p>
<h3>IsDefined</h3>
<p>Why does <code><a href="http://msdn.microsoft.com/en-us/library/system.enum.isdefined.aspx">IsDefined</a></code> throw an exception when you pass it an integral value that can be safely narrowed to the enumeration&#8217;s underlying type?</p>
<p>For example, this will throw an exception:</p>

<div class="wp_syntax"><div class="code"><pre class="csharp" style="font-family:Consolas, monospace;"><span style="color: #FF0000;">enum</span> Fruit <span style="color: #008000;">:</span> <span style="color: #FF0000;">byte</span> <span style="color: #000000;">&#123;</span> Apple, Orange, Cumquat <span style="color: #000000;">&#125;</span><span style="color: #008000;">;</span>
var defined <span style="color: #008000;">=</span> <span style="color: #FF0000;">Enum</span>.<span style="color: #0000FF;">IsDefined</span><span style="color: #000000;">&#40;</span> <span style="color: #008000;">typeof</span><span style="color: #000000;">&#40;</span>Fruit<span style="color: #000000;">&#41;</span>, <span style="color: #FF0000;">0</span> <span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span></pre></div></div>

<p>Why?  Because it&#8217;s a integer literal (and therefore type <code>int</code>) and the underlying type of <code>Fruit</code> is <code>byte</code>.  This would be alright if this is how the Enum class consistently treated this case, but it&#8217;s not.  In every other method, the Enum class is OK with you passing in an <code>int</code> value for a <code>byte</code> enumeration (as long as it&#8217;s within the range of the underlying type).</p>
<h3>ToObject</h3>
<p>Why does <code><a href="http://msdn.microsoft.com/en-us/library/system.enum.toobject.aspx">ToObject</a></code> silently overflow for values outside the range of the enumeration&#8217;s underlying type?</p>
<p>For example, this code will give the following non-intuitive result:</p>

<div class="wp_syntax"><div class="code"><pre class="csharp" style="font-family:Consolas, monospace;"><span style="color: #FF0000;">enum</span> Fruit <span style="color: #008000;">:</span> <span style="color: #FF0000;">byte</span> <span style="color: #000000;">&#123;</span> Apple, Orange, Cumquat <span style="color: #000000;">&#125;</span><span style="color: #008000;">;</span>
var apple <span style="color: #008000;">=</span> <span style="color: #FF0000;">Enum</span>.<span style="color: #0000FF;">ToObject</span><span style="color: #000000;">&#40;</span> <span style="color: #008000;">typeof</span><span style="color: #000000;">&#40;</span>Fruit<span style="color: #000000;">&#41;</span>, <span style="color: #FF0000;">0</span> <span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
var elppa <span style="color: #008000;">=</span> <span style="color: #FF0000;">Enum</span>.<span style="color: #0000FF;">ToObject</span><span style="color: #000000;">&#40;</span> <span style="color: #008000;">typeof</span><span style="color: #000000;">&#40;</span>Fruit<span style="color: #000000;">&#41;</span>, <span style="color: #FF0000;">256</span> <span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
Assert.<span style="color: #0000FF;">AreEqual</span><span style="color: #000000;">&#40;</span>apple, elppa<span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span></pre></div></div>

<p>Assuming that we ignore the fact that silently overflowing is typically a bad idea, this is again completely inconsistent with the rest of the library.  Why overflow here, but not in <code>GetName</code>?</p>
<h3>Conclusion</h3>
<p>The .NET Enum class is not lacking in it&#8217;s ability to extract any information you need from an enumeration.  It is, however, a little inconsistent in terms of how it treats underlying type mismatches, overflows and narrowing conversions.  Barring a new, generified Enum class from Microsoft, the best way to deal with these inconsistencies is to either be aware of them, or use a third-party library to hide them.</p>
<p><em>(Edit: Some people have noted that my conclusion was a bit weak and preachy towards Dnum, which I have to admit is not without truth.  I&#8217;ve seen edited it.  For the record, the old conclusion was: &#8220;Fortunately, these and other problems have been fixed in my <a href="http://cdmckay.org/blog/dnum/">Dnum</a> library, which should be released in the next couple days.  Be sure to check it out.&#8221;).</em></p>
]]></content:encoded>
			<wfw:commentRss>http://cdmckay.org/blog/2009/09/14/inconsistencies-in-the-net-enum-class/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
	</channel>
</rss>
