<?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>esmithy.net &#187; .NET</title>
	<atom:link href="http://esmithy.net/category/programming/dotnet/feed/" rel="self" type="application/rss+xml" />
	<link>http://esmithy.net</link>
	<description>Stuff Hammered Out by Eric Smith</description>
	<lastBuildDate>Fri, 02 Jul 2010 20:35:17 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>.NET Color Struct Equality</title>
		<link>http://esmithy.net/2009/12/16/net-color-struct-equality/</link>
		<comments>http://esmithy.net/2009/12/16/net-color-struct-equality/#comments</comments>
		<pubDate>Thu, 17 Dec 2009 00:47:55 +0000</pubDate>
		<dc:creator>Eric</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[Bafflers]]></category>

		<guid isPermaLink="false">http://esmithy.net/?p=322</guid>
		<description><![CDATA[When is white not white? When one is Color.White and the other is Color.FromArgb(0xff, 0xff, 0xff, 0xff). I was trying to data bind a list of colors to a ComboBox and have the SelectedValue property bound to a particular color. The frustrating thing was that even though there was a color matching the &#8220;selected&#8221; color [...]]]></description>
			<content:encoded><![CDATA[<p>When is white not white? When one is Color.White and the other is Color.FromArgb(0xff, 0xff, 0xff, 0xff).</p>
<p><span id="more-322"></span>I was trying to data bind a list of colors to a ComboBox and have the SelectedValue property bound to a particular color. The frustrating thing was that even though there was a color matching the &#8220;selected&#8221; color in the list, the ComboBox never had a selection when first displayed.</p>
<p>Eventually I discovered that my &#8220;selected&#8221; color was white (all color components at 255) while the list&#8217;s equivalent was Color.White. Careful reading of the <a href="http://msdn.microsoft.com/en-us/library/e03x8ct2.aspx">Color.Equals</a> documentation tells me that I was silly to think that white is white or black is black:</p>
<blockquote><p><span> <span><a id="ctl00_MTCS_main_ctl36_ctl00_ctl03" onclick="javascript:Track('ctl00_MTCS_main_ctl36_ctl00_contenthere|ctl00_MTCS_main_ctl36_ctl00_ctl03',this);" href="http://msdn.microsoft.com/en-us/library/system.drawing.color.black.aspx">Black</a></span> and <span class="code">FromArgb(0,0,0)</span> are not considered equal, since <span><a id="ctl00_MTCS_main_ctl36_ctl00_ctl04" onclick="javascript:Track('ctl00_MTCS_main_ctl36_ctl00_contenthere|ctl00_MTCS_main_ctl36_ctl00_ctl04',this);" href="http://msdn.microsoft.com/en-us/library/system.drawing.color.black.aspx">Black</a></span> is a named color and <span class="code">FromArgb(0,0,0)</span> is not.</span></p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://esmithy.net/2009/12/16/net-color-struct-equality/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Transparent WinForms Label</title>
		<link>http://esmithy.net/2009/11/28/transparent-winforms-label/</link>
		<comments>http://esmithy.net/2009/11/28/transparent-winforms-label/#comments</comments>
		<pubDate>Sat, 28 Nov 2009 18:40:41 +0000</pubDate>
		<dc:creator>Eric</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[User Interface]]></category>
		<category><![CDATA[Windows]]></category>

		<guid isPermaLink="false">http://esmithy.net/?p=315</guid>
		<description><![CDATA[Easy control transparency isn&#8217;t exactly a hallmark of Windows Forms. If you have a form with a background image or a gradient, the stock controls paint with a solid background to give a criminally egregious aesthetic. If you search the web for a solution, you might come up with a couple of proposed solutions: WinForms: [...]]]></description>
			<content:encoded><![CDATA[<p>Easy control transparency isn&#8217;t exactly a hallmark of Windows Forms. If you have a form with a background image or a gradient, the stock controls paint with a solid background to give a criminally egregious aesthetic.</p>
<p><span id="more-315"></span>If you search the web for a solution, you might come up with a couple of proposed solutions:</p>
<ul>
<li><a href="http://support.microsoft.com/kb/943454">WinForms: How to create a control transparent to other controls</a> &#8211; The official word from Microsoft, the solution is presented in several pages of poorly formatted VB code that makes you immediately want to look for something simpler, such as&#8230;</li>
<li><a href="http://www.doogal.co.uk/transparent.php">C# Transparent Label</a> (also <a href="http://www.west-wind.com/WebLog/posts/247977.aspx">referenced</a> from Rick Strahl&#8217;s blog) &#8211; This solution is much simpler; it&#8217;s just a Control subclass that doesn&#8217;t paint a background and draws the label text in OnPaint.</li>
</ul>
<p>After working with the second solution for a while, I discovered that it doesn&#8217;t handle updating the text very well. Just changing the Text property itself doesn&#8217;t do it, and if you invalidate the control, you get the new text painted over the old text. If you&#8217;re the kind of person who fusses about minutiae like <em>legibility</em> and such, this isn&#8217;t ideal.</p>
<p>So here&#8217;s a solution that has worked reasonably well for me, and that scores high marks in the simplicity category:</p>

<div class="wp_syntax"><div class="code"><pre class="csharp" style="font-family:monospace;"><span style="color: #008080; font-style: italic;">/// </span>
<span style="color: #008080; font-style: italic;">/// A label that is transparent.</span>
<span style="color: #008080; font-style: italic;">/// </span>
<span style="color: #0600FF;">public</span> <span style="color: #FF0000;">class</span> TransparentLabel <span style="color: #008000;">:</span> Label
<span style="color: #000000;">&#123;</span>
  <span style="color: #008080; font-style: italic;">/// </span>
  <span style="color: #008080; font-style: italic;">/// Paints the background with the parent's background image.</span>
  <span style="color: #008080; font-style: italic;">/// </span>
  <span style="color: #008080; font-style: italic;">///</span>
e
  <span style="color: #0600FF;">protected</span> <span style="color: #0600FF;">override</span> <span style="color: #0600FF;">void</span> OnPaintBackground<span style="color: #000000;">&#40;</span>PaintEventArgs e<span style="color: #000000;">&#41;</span>
  <span style="color: #000000;">&#123;</span>
    Rectangle rect <span style="color: #008000;">=</span> <span style="color: #008000;">new</span> Rectangle<span style="color: #000000;">&#40;</span>Location, Size<span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
    e.<span style="color: #0000FF;">Graphics</span>.<span style="color: #0000FF;">DrawImage</span><span style="color: #000000;">&#40;</span>Parent.<span style="color: #0000FF;">BackgroundImage</span>, <span style="color: #FF0000;">0</span>, <span style="color: #FF0000;">0</span>, rect, GraphicsUnit.<span style="color: #0000FF;">Pixel</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
  <span style="color: #000000;">&#125;</span>
<span style="color: #000000;">&#125;</span></pre></div></div>

<p>It basically scoops up the correct part of the parent&#8217;s background image and uses it as the background for the control. Yes, it still isn&#8217;t transparency, just a much better job of &#8220;camouflage&#8221; than the default behavior. If you&#8217;re painting the parent&#8217;s background, with a gradient brush for example, you can paint that into a bitmap instead and set the parent&#8217;s BackgroundImage to the bitmap for this solution to still work.</p>
]]></content:encoded>
			<wfw:commentRss>http://esmithy.net/2009/11/28/transparent-winforms-label/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Rounded Rectangluar Regions</title>
		<link>http://esmithy.net/2009/11/19/rounded-rectangluar-regions/</link>
		<comments>http://esmithy.net/2009/11/19/rounded-rectangluar-regions/#comments</comments>
		<pubDate>Fri, 20 Nov 2009 04:27:27 +0000</pubDate>
		<dc:creator>Eric</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Windows]]></category>

		<guid isPermaLink="false">http://esmithy.net/?p=302</guid>
		<description><![CDATA[There are lots of examples that demonstrate how to draw a rectangle with rounded corners using GDI+ in .NET. Converting such a rectangle to a Region so that it can be filled or be used for the geometry of a window can have less than perfect results, though. For example, here is one of the [...]]]></description>
			<content:encoded><![CDATA[<p>There are lots of examples that demonstrate how to draw a rectangle with rounded corners using GDI+ in .NET. Converting such a rectangle to a Region so that it can be filled or be used for the geometry of a window can have less than perfect results, though.<br />
<span id="more-302"></span><br />
For example, here is one of the more concise methods for getting a rounded Rectangle:</p>

<div class="wp_syntax"><div class="code"><pre class="csharp" style="font-family:monospace;"><span style="color: #0600FF;">public</span> <span style="color: #0600FF;">static</span> GraphicsPath GetRoundedRectangle<span style="color: #000000;">&#40;</span>Rectangle rect, <span style="color: #FF0000;">int</span> rad<span style="color: #000000;">&#41;</span>
<span style="color: #000000;">&#123;</span>
	<span style="color: #FF0000;">int</span> d <span style="color: #008000;">=</span> <span style="color: #FF0000;">2</span> <span style="color: #008000;">*</span> rad<span style="color: #008000;">;</span>
	<span style="color: #000000;">System.<span style="color: #0000FF;">Drawing</span>.<span style="color: #0000FF;">Drawing2D</span></span>.<span style="color: #0000FF;">GraphicsPath</span> gp <span style="color: #008000;">=</span>
			<span style="color: #008000;">new</span> <span style="color: #000000;">System.<span style="color: #0000FF;">Drawing</span>.<span style="color: #0000FF;">Drawing2D</span></span>.<span style="color: #0000FF;">GraphicsPath</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
&nbsp;
	gp.<span style="color: #0000FF;">AddArc</span><span style="color: #000000;">&#40;</span>rect.<span style="color: #0000FF;">X</span>, rect.<span style="color: #0000FF;">Y</span>, d, d, <span style="color: #FF0000;">180</span>, <span style="color: #FF0000;">90</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
	gp.<span style="color: #0000FF;">AddArc</span><span style="color: #000000;">&#40;</span>rect.<span style="color: #0000FF;">X</span> <span style="color: #008000;">+</span> rect.<span style="color: #0000FF;">Width</span> <span style="color: #008000;">-</span> d, rect.<span style="color: #0000FF;">Y</span>, d, d, <span style="color: #FF0000;">270</span>, <span style="color: #FF0000;">90</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
	gp.<span style="color: #0000FF;">AddArc</span><span style="color: #000000;">&#40;</span>rect.<span style="color: #0000FF;">X</span> <span style="color: #008000;">+</span> rect.<span style="color: #0000FF;">Width</span> <span style="color: #008000;">-</span> d, rect.<span style="color: #0000FF;">Y</span> <span style="color: #008000;">+</span> rect.<span style="color: #0000FF;">Height</span> <span style="color: #008000;">-</span> d, d, d, <span style="color: #FF0000;">0</span>, <span style="color: #FF0000;">90</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
	gp.<span style="color: #0000FF;">AddArc</span><span style="color: #000000;">&#40;</span>rect.<span style="color: #0000FF;">X</span>, rect.<span style="color: #0000FF;">Y</span> <span style="color: #008000;">+</span> rect.<span style="color: #0000FF;">Height</span> <span style="color: #008000;">-</span> d, d, d, <span style="color: #FF0000;">90</span>, <span style="color: #FF0000;">90</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
	gp.<span style="color: #0000FF;">AddLine</span><span style="color: #000000;">&#40;</span>rect.<span style="color: #0000FF;">X</span>, rect.<span style="color: #0000FF;">Y</span> <span style="color: #008000;">+</span> rect.<span style="color: #0000FF;">Height</span> <span style="color: #008000;">-</span> d, rect.<span style="color: #0000FF;">X</span>, rect.<span style="color: #0000FF;">Y</span> <span style="color: #008000;">+</span> d <span style="color: #008000;">/</span> <span style="color: #FF0000;">2</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
&nbsp;
	<span style="color: #0600FF;">return</span> gp<span style="color: #008000;">;</span>
<span style="color: #000000;">&#125;</span></pre></div></div>

<p>It&#8217;s trivial to convert that GraphicsPath to a Region &#8212; just call the appropriate Region constructor. You can then fill the region:</p>

<div class="wp_syntax"><div class="code"><pre class="csharp" style="font-family:monospace;">var path <span style="color: #008000;">=</span> GetRoundedRectangle<span style="color: #000000;">&#40;</span>rect, <span style="color: #FF0000;">3</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
e.<span style="color: #0000FF;">Graphics</span>.<span style="color: #0000FF;">FillRegion</span><span style="color: #000000;">&#40;</span>Brushes.<span style="color: #0000FF;">Orange</span>, <span style="color: #008000;">new</span> Region<span style="color: #000000;">&#40;</span>path<span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span></pre></div></div>

<p>If your corner radius is sufficiently large, you might not notice anything wrong with the result. With a value of 3, it is pretty obvious:</p>
<p style="text-align: center;"><img class="size-full wp-image-303 aligncenter" title="Not-so-rounded rectangle" src="http://esmithy.net/content/rect-bad.png" alt="Not-so-rounded rectangle" width="321" height="191" /></p>
<p>The top left corner looks perfect:</p>
<p style="text-align: center;"><img class="aligncenter size-full wp-image-308" title="Top-left" src="http://esmithy.net/content/rect-topleft.png" alt="Top-left" width="105" height="105" /></p>
<p>The bottom right corner is decidedly un-round:</p>
<p style="text-align: center;"><img class="aligncenter size-full wp-image-309" title="Bottom-right" src="http://esmithy.net/content/rect-bottomright1.png" alt="Bottom-right" width="120" height="126" /></p>
<p>I started to wonder if all those round rectangle functions were wrong, but drawing the GraphicsPath itself shows that the code is correct:</p>
<p style="text-align: center;"><img class="size-full wp-image-307 aligncenter" title="Graphics Path" src="http://esmithy.net/content/rect-path.png" alt="Graphics Path" width="329" height="200" /></p>
<p>The problem is that when converting the GraphicsPath to a Region, it uses the <em>inside </em>of the GraphicsPath, so you lose the outside pixels on the sides, which you can see when drawing the path and then filling the region:</p>
<p style="text-align: center;"><img class="aligncenter size-full wp-image-305" title="Missing pixels in the region" src="http://esmithy.net/content/rect-detail.png" alt="rect-detail" width="310" height="181" /></p>
<p>It turns out to be a whole lot easier and effective to do a little p/invoke here:</p>

<div class="wp_syntax"><div class="code"><pre class="csharp" style="font-family:monospace;"><span style="color: #000000;">&#91;</span>DllImport<span style="color: #000000;">&#40;</span><span style="color: #666666;">&quot;gdi32.dll&quot;</span><span style="color: #000000;">&#41;</span><span style="color: #000000;">&#93;</span>
<span style="color: #0600FF;">static</span> <span style="color: #0600FF;">extern</span> IntPtr CreateRoundRectRgn<span style="color: #000000;">&#40;</span><span style="color: #FF0000;">int</span> x1, <span style="color: #FF0000;">int</span> y1, <span style="color: #FF0000;">int</span> x2, <span style="color: #FF0000;">int</span> y2, <span style="color: #FF0000;">int</span> cx, <span style="color: #FF0000;">int</span> cy<span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
<span style="color: #008080; font-style: italic;">// ...</span>
var region <span style="color: #008000;">=</span> Region.<span style="color: #0000FF;">FromHrgn</span><span style="color: #000000;">&#40;</span>CreateRoundRectRgn<span style="color: #000000;">&#40;</span>rect.<span style="color: #0000FF;">X</span>, rect.<span style="color: #0000FF;">Y</span>, rect.<span style="color: #0000FF;">X</span> <span style="color: #008000;">+</span> rect.<span style="color: #0000FF;">Width</span>, rect.<span style="color: #0000FF;">Y</span> <span style="color: #008000;">+</span> rect.<span style="color: #0000FF;">Height</span>, <span style="color: #FF0000;">3</span>, <span style="color: #FF0000;">3</span><span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
e.<span style="color: #0000FF;">Graphics</span>.<span style="color: #0000FF;">FillRegion</span><span style="color: #000000;">&#40;</span>Brushes.<span style="color: #0000FF;">Orange</span>, region<span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span></pre></div></div>

<p>Here&#8217;s the output from that code:</p>
<p style="text-align: center;"><img class="aligncenter size-full wp-image-306" title="Good Region" src="http://esmithy.net/content/rect-good.png" alt="Good Region" width="310" height="182" /></p>
<p>It looks like a little larger corner radius is needed to get the same rounding, but otherwise it is perfect.</p>
]]></content:encoded>
			<wfw:commentRss>http://esmithy.net/2009/11/19/rounded-rectangluar-regions/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The Best of PDC 2008</title>
		<link>http://esmithy.net/2009/01/17/the-best-of-pdc-2008/</link>
		<comments>http://esmithy.net/2009/01/17/the-best-of-pdc-2008/#comments</comments>
		<pubDate>Sun, 18 Jan 2009 04:45:22 +0000</pubDate>
		<dc:creator>Eric</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[Software Development]]></category>

		<guid isPermaLink="false">http://esmithy.net/?p=218</guid>
		<description><![CDATA[For those of us poor folk who didn&#8217;t make it to PDC this past fall, Microsoft has been taking the show to us in the form of its MSDN Unleashed series. Rob Bagby, developer evangelist, came to Salt Lake City to present and give updates about new and upcoming technologies for developers. The Future of [...]]]></description>
			<content:encoded><![CDATA[<p>For those of us poor folk who didn&#8217;t make it to PDC this past fall, Microsoft has been taking the show to us in the form of its MSDN Unleashed series. <a href="http://blogs.msdn.com/bags/">Rob Bagby</a>, developer evangelist, came to Salt Lake City to present and give updates about new and upcoming technologies for developers.</p>
<p style="text-align: center;"><img class="aligncenter size-full wp-image-219" title="Microsoft\'s Salt Lake City Office" src="http://esmithy.net/content/microsoft-slc.jpg" alt="" width="400" height="231" /></p>
<p><span id="more-218"></span></p>
<p><strong>The Future of C# (AKA C# 4)</strong></p>
<p>Rob&#8217;s first presentation introduced what the C# team is working on for the next release of the language. A lot of the focus is around exposing support for dynamic programming and interoperability with dynamic languages like Python and Ruby. This is done by deferring the evaluation of method and property calls on some objects until runtime. At compile time, the normally strict static type checking of the C# compiler is relaxed when a method call doesn&#8217;t seem to exist in order to allow for the possibility that such a method will be added dynamically sometime during program execution. To indicate that this behavior is wanted, you use the <strong>dynamic</strong> keyword like this:</p>

<div class="wp_syntax"><div class="code"><pre class="cs" style="font-family:monospace;">dynamic customer = GetCustomer();
Console.WriteLine(customer.FirstName);</pre></div></div>

<p>At run time, whatever actual object is stored in &#8220;customer&#8221; needs to have a property &#8220;FirstName&#8221; or an exception is thrown. Otherwise, the actual type is unimportant. This is also known as &#8220;duck typing&#8221; where capabilities of objects are more important than actual types &#8212; if it looks like a duck and acts like a duck, it might as well be a duck.</p>
<p>Some people in attendance were confused about how the <strong>dynamic</strong> keyword differs from <strong>var</strong>. The <strong>var</strong> keyword really just saves keystrokes &#8212; the type is still static but figured out by the compiler. Objects that are <strong>dynamic</strong> however, have their method calls bound at run time.</p>
<p>The ability of C# to handle dynamic types also makes it easier to interoperate with Javascript. Rob showed a Silverlight application that called out to Javascript functions pretty much identically to calling regular C# methods.</p>
<p>The next version of C# will also have default and named parameters, which have been supported in other .NET languages, and will make COM interop a bit nicer. I&#8217;ve written a bunch of calls to Office where it seems like you&#8217;re passing in ten-thousand Type.Missing parameters to some of the methods, and that will no longer be required.</p>
<p><strong>Silverlight Toolkit</strong></p>
<p>Shawn Burke, one of the guys behind the AJAX Control Toolkit, is now <a href="http://blogs.msdn.com/sburke/archive/2008/09/17/control-freak.aspx">heading a team to create Silverlight controls</a>. This presentation showed the controls that they are working on, and described the distribution model.</p>
<p>The controls are things like AutoComplete, NumericUpDown, TreeView, DockPanel, WrapPanel, and others that would be really useful in building a typical modern GUI application. There is also charting support, which Rob said comes fairly mature by virtue of Microsoft&#8217;s assimilation of Dundas code and engineers. There is also support for theming applications.</p>
<p>The controls are to be released on CodePlex frequently, with some controls eventually making it into the official Silverlight SDK or even the Silverlight Core. The <a href="http://www.codeplex.com/Silverlight">Silverlight Toolkit</a>, not to be confused with a CodePlex project called the <a href="http://www.codeplex.com/SilverlightToolkit">Silverlight Control Toolkit</a>, has a nice sample application that shows off all the new components.</p>
<p><strong>REST with WCF</strong></p>
<p>My coworker, <a href="http://www.zombiecuisine.com/">Ryan Jameson</a>, went to a Microsoft event last year where the <a href="http://msdn.microsoft.com/en-us/netframework/cc950529.aspx">REST Starter Kit for WCF</a> was one of the topics. He came back saying with a smirk that Microsoft had apparently <em>invented</em> REST, the way they had presented it. Rob implied no such thing, even joking that in every presentation about REST, there are people ranging from those who have never heard of it, to those that know <a href="http://en.wikipedia.org/wiki/Roy_Fielding">Roy Fielding&#8217;s</a> middle initial (which would be T, by the way).</p>
<p>REST is a philosophy for providing web services in a way that embraces the &#8220;way of the web&#8221;, such as:</p>
<ul>
<li>Most everything is addressable through a URI</li>
<li>There are standard representation formats</li>
<li>Interactions are stateless</li>
<li>The HTTP protocol</li>
</ul>
<p>Rob asked rhetorically if these principles might work OK given the success of the web, and summed up the philosophy by saying, &#8220;If you use GET for something other than <em>getting</em> a resource, you&#8217;re Part of the Problem.&#8221; And don&#8217;t even think about using POST to <em>get</em> something.</p>
<p>I haven&#8217;t done more than play around with web services, but it seemed to me that by using URI templates, WebGet and WebInvoke attributes, and WebProtocolException, you could suffuse a high degree of RESTiness into your WCF web service.</p>
<p>Things got pretty loose in this presentation, with Rob dodging pot shots about IE and standards conformance, switching to a Mexican accent for a bit of the delivery, and demonstrating that Notepad is a REST client. Kind of fun.</p>
<p><strong>Azure</strong></p>
<p>The last presentation was a lot to grasp, as Rob warned it would be. The denotation of &#8220;azure&#8221; is the blue of a clear or unclouded sky. But Microsoft&#8217;s Azure is about cloud computing. What does that mean?</p>
<p>Azure comprises a huge pile of stuff, which makes it pretty hard to talk about in a meaningful way. Hearing the presentation reminded me of when .NET was first announced. Everything at Microsoft was .NET then: Visual Studio .NET, Windows .NET, Clippy .NET, etc. The short version is that Azure combines typical operating system facilities with utility computing. In one sense it sounds like outsourced IT, where you let Microsoft worry about the data center, dynamically scaling resources as needed. But it is also more than that &#8212; an umbrella of networked stuff covering the &#8220;Live&#8221; services, SQL, raw data storage, and much more.</p>
<p>Rob says that Azure is Microsoft&#8217;s big bet right now. I wonder if things will settle down a bit when Microsoft gets a more fully-formed vision, much like they did with .NET.</p>
]]></content:encoded>
			<wfw:commentRss>http://esmithy.net/2009/01/17/the-best-of-pdc-2008/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>.NET Cold Startup Performance: More</title>
		<link>http://esmithy.net/2008/06/03/net-cold-startup-performance-more/</link>
		<comments>http://esmithy.net/2008/06/03/net-cold-startup-performance-more/#comments</comments>
		<pubDate>Tue, 03 Jun 2008 23:36:13 +0000</pubDate>
		<dc:creator>Eric</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[Office]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://esmithy.net/?p=132</guid>
		<description><![CDATA[A few months ago I wrote about an approach to improving .NET cold startup performance. Here&#8217;s a little more information that I&#8217;ve learned since then. Another useful tool for optimizing cold startup is Microsoft&#8217;s free CLR Profiler 2.0. While this tool has the aesthetics of a wadded-up paper sack, it does have the ability to graph each assembly that gets [...]]]></description>
			<content:encoded><![CDATA[<p>A few months ago <a href="2008/03/06/net-cold-startup-performance-an-example/">I wrote about</a> an approach to improving .NET cold startup performance. Here&#8217;s a little more information that I&#8217;ve learned since then.</p>
<p><span id="more-132"></span>Another useful tool for optimizing cold startup is Microsoft&#8217;s free <a href="http://www.microsoft.com/downloads/details.aspx?familyid=A362781C-3870-43BE-8926-862B40AA0CD0&#038;displaylang=en">CLR Profiler 2.0</a>. While this tool has the aesthetics of a wadded-up paper sack, it does have the ability to graph each assembly that gets loaded, and the method that caused it to be loaded. This makes it easier to figure out <em>why</em> a particular assembly got loaded, allowing you to consider whether there might be a way to avoid loading it or postpone loading it until some less critical moment.</p>
<p>To generate the assembly graph, click the <strong>Start Application</strong> button in the profiler. It lets you browse to the executable, which it will then launch. When you close the application, the profiler displays a summary screen with a bunch of information about the managed heap and garbage collection. You can close that window. Instead, go to the main menu and pick <strong>View</strong> &gt; <strong>Assembly Graph</strong>. You&#8217;ll see something like this:</p>
<p style="text-align: center;"> <a href="http://esmithy.net/content/assembly-graph.png"><img class="alignnone size-medium wp-image-133" title="Assembly Graph Window" src="http://esmithy.net/content/assembly-graph-300x181.png" alt="" width="300" height="181" /></a></p>
<p style="text-align: center;">Assembly Graph Window (click for larger image)</p>
<p style="text-align: left;">At the far left edge of the graph, you can see the total number of assemblies (30) that were loaded during the application run. The edges from there represent method calls that caused other assemblies to load. Underneath the method name is the total number assemblies loaded through the full call stack. As you move to the far right side of the graph, you eventually see each individual assembly that is loaded. If you click on a node in the graph it sort of highlights (is <em>plaid</em> technically a highlight color?) the edges in and out of the node. That can be really handy when the graph lines criss-cross over each other.</p>
<p style="text-align: left;">In my case, where I&#8217;m writing a Word add-in, I have some initialization that must happen on the main thread at startup. Other initialization is put on a low priority background thread, which allows Word to start up quickly while continuing to load up the add-in functionality for when it will be used. To get a better picture of startup, I commented out the background thread. Then I looked for call paths that loaded lots of assemblies to figure out if any of those could be deferred to the background thread.</p>
<p style="text-align: left;">I found that making an XML-RPC call was pretty expensive in terms of code loading. The RPC call itself was pretty fast &#8212; just talking to another process on the same machine, but it took loading classes from five additional assemblies just to make the call, which hurts cold startup performance. At this point we&#8217;re trying to figure out if the current performance is acceptable or if we need to tweak the add-in&#8217;s behavior a little to delay the RPC call to the background thread. </p>
]]></content:encoded>
			<wfw:commentRss>http://esmithy.net/2008/06/03/net-cold-startup-performance-more/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Are .NET Properties a Mistake?</title>
		<link>http://esmithy.net/2008/04/24/are-net-properties-a-mistake/</link>
		<comments>http://esmithy.net/2008/04/24/are-net-properties-a-mistake/#comments</comments>
		<pubDate>Fri, 25 Apr 2008 03:28:02 +0000</pubDate>
		<dc:creator>Eric</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://esmithy.net/2008/04/24/are-net-properties-a-mistake/</guid>
		<description><![CDATA[As I mentioned the other day, I&#8217;m reading Jeffrey Richter&#8217;s book CLR via C# right now. I was kind of surprised to read this statement by the author: &#8220;If I had been involved in the design of the .NET Framework and compilers, I would not have offered properties at all&#8230;&#8221; (p. 218) Mr. Richter&#8217;s reason [...]]]></description>
			<content:encoded><![CDATA[<p>As I mentioned the other day, I&#8217;m reading Jeffrey Richter&#8217;s book <em>CLR via C#</em> right now. I was kind of surprised to read this statement by the author: &#8220;If I had been involved in the design of the .NET Framework and compilers, I would not have offered properties at all&#8230;&#8221; (p. 218)<span id="more-131"></span></p>
<p>Mr. Richter&#8217;s reason for disliking properties is that they look like fields but don&#8217;t behave like them, thus confusing developers. He gives a good list of ways in which properties are different from fields &#8212; think of all the ways that a zero argument method is different from a field and you&#8217;ll about have it &#8212; saying that those differences are bound to trip people up.</p>
<p>I disagree for a couple of reasons:</p>
<ol>
<li>Properties are really pretty easy to grasp.</li>
<li>Most programmers adhere to the rule that all fields are private (which Mr. Richter also recommended), so there aren&#8217;t really fields to be confused by. Expect everything to be a method and you&#8217;ll generally be fine.</li>
</ol>
<p>I say &#8220;generally&#8221; because there are some cases where the opposite is true: a property can behave more like a field than a method. For example, you can use the <a href="http://msdn.microsoft.com/en-us/library/aa691363(VS.71).aspx">postfix increment operator</a> on a property (that has both get and set accessors) and it behaves as it would on a field. That is, the operator gets the property value and sets the incremented value back in. [Added June 26, 2008]</p>
<p>A benefit of properties that isn&#8217;t really mentioned in the book is a more explicit (for lack of a better word) &#8220;bean-ness&#8221;. Java has the bean concept, where an object has get and set methods to create a set of properties, but the C# syntax is more elegant and apparent. With the explicit properties, you can do things like XML serialization, property editors, etc. with reasonable default behavior.</p>
<p>It&#8217;s probably true that .NET properties get abused and overused (see the <a href="http://msdn2.microsoft.com/en-us/library/ms229006.aspx">official guidelines</a>), but I still kind of like them.</p>
]]></content:encoded>
			<wfw:commentRss>http://esmithy.net/2008/04/24/are-net-properties-a-mistake/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>.NET Cold Startup Performance: An Example</title>
		<link>http://esmithy.net/2008/03/06/net-cold-startup-performance-an-example/</link>
		<comments>http://esmithy.net/2008/03/06/net-cold-startup-performance-an-example/#comments</comments>
		<pubDate>Fri, 07 Mar 2008 00:19:29 +0000</pubDate>
		<dc:creator>Eric</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://esmithy.net/2008/03/06/net-cold-startup-performance-an-example/</guid>
		<description><![CDATA[When running a .NET application for the first time after rebooting or hibernating the computer, you might find that it takes a long time to start up. I&#8217;ve been trying to address this problem in a few situations recently. In spite of having read several articles on the subject, I wasn&#8217;t having much success. Following some of [...]]]></description>
			<content:encoded><![CDATA[<p>When running a .NET application for the first time after rebooting or hibernating the computer, you might find that it takes a long time to start up. I&#8217;ve been trying to address this problem in a few situations recently. In spite of having read several articles on the subject, I wasn&#8217;t having much success. Following some of the advice gave no noticeable improvement, and some (like using NGEN) actually slowed down startup. But I had some success recently, so I thought I&#8217;d explain how.</p>
<p><span id="more-127"></span></p>
<p>First of all, it&#8217;s important to understand that the CLR itself loads up pretty fast. If you create &#8220;Hello, world&#8221;, even using Windows Forms, it starts almost instantly. As things get more complicated, though, you start loading more and more assemblies and classes, and the time to read all of those from disk (possibly combined with other I/O your application might do) is what makes cold startup so slow. If the application starts really fast on the next run, that&#8217;s because all of those assemblies and classes are cached, and physical disk reads aren&#8217;t necessary. </p>
<p>I&#8217;m working on an add-in that runs in Word, Excel and PowerPoint. One of the objectives was to minimize the startup impact on the host application, so I started measuring it using an early implementation of the add-in. The results were not promising. On a low end machine, cold startup with the add-in took 18 seconds, compared to 8 seconds for the application without the add-in.</p>
<p>Performance Monitor has some useful counters for measuring your optimization. In my case, I added the .NET CLR Loading object&#8217;s &#8220;Total Assemblies&#8221; and &#8220;Total Classes Loaded&#8221; counters for WINWORD:</p>
<p align="center"><img src="http://esmithy.net/content/cold-start-add-counters.jpg" alt="Performance Counters Dialog" /></p>
<p>&#8220;Report&#8221; view is best for these. It just shows the plain numeric values of the counters. I discovered that I had 19 assemblies and 517 classes being loaded at startup. My strategy was to reduce those two numbers and hope that I&#8217;d see a corresponding improvement in startup time.</p>
<p>Next I used Visual Studio to debug the add-in, paying attention to the Modules window. This isn&#8217;t totally reliable in terms of figuring out what code loaded what modules since the debugger does things like call properties on objects while it is running, but it is still kind of useful. One thing jumped out at me right away. Even though I was running my add-in in Word, the interop assemblies for Excel and PowerPoint were also loaded. Looking at the code, I saw this:</p>

<div class="wp_syntax"><div class="code"><pre class="csharp" style="font-family:monospace;">Word.<span style="color: #0000FF;">Application</span> wordApp <span style="color: #008000;">=</span> hostApplicationObject <span style="color: #0600FF;">as</span> Word.<span style="color: #0000FF;">Application</span><span style="color: #008000;">;</span>
<span style="color: #0600FF;">if</span> <span style="color: #000000;">&#40;</span>wordApp <span style="color: #008000;">!=</span> <span style="color: #0600FF;">null</span><span style="color: #000000;">&#41;</span>
<span style="color: #000000;">&#123;</span>
  application <span style="color: #008000;">=</span> <span style="color: #008000;">new</span> WordApplication<span style="color: #000000;">&#40;</span>wordApp<span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
  return<span style="color: #008000;">;</span>
<span style="color: #000000;">&#125;</span> 
&nbsp;
Excel.<span style="color: #0000FF;">Application</span> excelApp <span style="color: #008000;">=</span> hostApplicationObject <span style="color: #0600FF;">as</span> Excel.<span style="color: #0000FF;">Application</span><span style="color: #008000;">;</span>
<span style="color: #0600FF;">if</span> <span style="color: #000000;">&#40;</span>excelApp <span style="color: #008000;">!=</span> <span style="color: #0600FF;">null</span><span style="color: #000000;">&#41;</span>
<span style="color: #000000;">&#123;</span>
  application <span style="color: #008000;">=</span> <span style="color: #008000;">new</span> ExcelApplication<span style="color: #000000;">&#40;</span>excelApp<span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
  return<span style="color: #008000;">;</span>
<span style="color: #000000;">&#125;</span>  
&nbsp;
PowerPoint.<span style="color: #0000FF;">Application</span> powerPointApp <span style="color: #008000;">=</span> hostApplicationObject <span style="color: #0600FF;">as</span> PowerPoint.<span style="color: #0000FF;">Application</span><span style="color: #008000;">;</span>
<span style="color: #0600FF;">if</span> <span style="color: #000000;">&#40;</span>powerPointApp <span style="color: #008000;">!=</span> <span style="color: #0600FF;">null</span><span style="color: #000000;">&#41;</span>
<span style="color: #000000;">&#123;</span>
  application <span style="color: #008000;">=</span> <span style="color: #008000;">new</span> PowerPointApplication<span style="color: #000000;">&#40;</span>powerPointApp<span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
  return<span style="color: #008000;">;</span>
<span style="color: #000000;">&#125;</span>
<span style="color: #0600FF;">throw</span> <span style="color: #008000;">new</span> NotSupportedException<span style="color: #000000;">&#40;</span><span style="color: #666666;">&quot;Unsupported application&quot;</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span></pre></div></div>

<p>Here the add-in is figuring out which application is running and initializing itself accordingly. The problem is that when the JIT compiler compiles the method with this code, it needs to load Word.Application, Excel.Application and PowerPoint.Application from the three interop assemblies.</p>
<p>I changed the code in two ways to fix this. First, instead of detecting the application by casting to the various Application objects, I used the name of the process. Second, I split the code that references each Application object into separate methods:</p>

<div class="wp_syntax"><div class="code"><pre class="csharp" style="font-family:monospace;"><span style="color: #FF0000;">string</span> processName <span style="color: #008000;">=</span> Process.<span style="color: #0000FF;">GetCurrentProcess</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>.<span style="color: #0000FF;">ProcessName</span><span style="color: #008000;">;</span>  
&nbsp;
<span style="color: #0600FF;">switch</span> <span style="color: #000000;">&#40;</span>processName<span style="color: #000000;">&#41;</span>
<span style="color: #000000;">&#123;</span>
  <span style="color: #0600FF;">case</span> <span style="color: #666666;">&quot;WINWORD&quot;</span><span style="color: #008000;">:</span>
    GetWordObjects<span style="color: #000000;">&#40;</span><span style="color: #0600FF;">ref</span> application, <span style="color: #0600FF;">ref</span> uiManager<span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
    break<span style="color: #008000;">;</span>   
&nbsp;
  <span style="color: #0600FF;">case</span> <span style="color: #666666;">&quot;EXCEL&quot;</span><span style="color: #008000;">:</span>
    GetExcelObjects<span style="color: #000000;">&#40;</span><span style="color: #0600FF;">ref</span> application, <span style="color: #0600FF;">ref</span> uiManager<span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
    break<span style="color: #008000;">;</span>  
&nbsp;
<span style="color: #0600FF;">case</span> <span style="color: #666666;">&quot;POWERPNT&quot;</span><span style="color: #008000;">:</span>
    GetPowerPointObjects<span style="color: #000000;">&#40;</span><span style="color: #0600FF;">ref</span> application, <span style="color: #0600FF;">ref</span> uiManager<span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
    break<span style="color: #008000;">;</span>  
&nbsp;
<span style="color: #0600FF;">default</span><span style="color: #008000;">:</span>
    <span style="color: #0600FF;">throw</span> <span style="color: #008000;">new</span> NotSupportedException<span style="color: #000000;">&#40;</span><span style="color: #666666;">&quot;Unsupported application: &quot;</span> <span style="color: #008000;">+</span> processName<span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
<span style="color: #000000;">&#125;</span></pre></div></div>

<p>Another thing I discovered in the debugger is that the logger we&#8217;re using, NLog, has some pretty heavy initialization. Typical usage of NLog is to have a static member of a class like this:</p>

<div class="wp_syntax"><div class="code"><pre class="csharp" style="font-family:monospace;"><span style="color: #0600FF;">private</span> <span style="color: #0600FF;">static</span> Logger logger <span style="color: #008000;">=</span> LogManager.<span style="color: #0000FF;">GetCurrentClassLogger</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span></pre></div></div>

<p>The problem here is that the logger starts up at type initialization time, dragging in System.Configuration, System.Xml, System.Web (!?), System.KitchenSink, etc.</p>
<p>Instead of doing this, I created a property that would get the logger on demand, and then made sure that I didn&#8217;t log anything on startup unless I had to log an error. It wasn&#8217;t enough to just say, &#8220;Oh, this is just at DEBUG log level, so that&#8217;s OK.&#8221; If there was <strong>any</strong> logging, regardless of level, it would require that the logger be initialized even to figure out that it didn&#8217;t need to actually log anything.</p>
<p>I made a couple of other optimizations. First was to defer calling Application.EnableVisualStyles until after startup (a luxury for my situation since I didn&#8217;t have to show UI right away) which saved me from having to bring in System.Windows.Forms. Another was to avoid using Debug.Assert. In this case, at NextPage we have a &#8220;Verify&#8221; utility class in a common library that has similar functionality. Since I was already loading Common.dll, I used that instead.</p>
<p>After these changes, my performance counters showed 13 assemblies and 175 classes loaded. Word was now starting in just 11 seconds instead of 18 with the unoptimized add-in. There&#8217;s still potential for some more improvement, but that is good enough to let me continue with implementation without the fear that startup time would be unacceptable.</p>
]]></content:encoded>
			<wfw:commentRss>http://esmithy.net/2008/03/06/net-cold-startup-performance-an-example/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Getting the Host&#8217;s Main Window Handle in an Office Add-in</title>
		<link>http://esmithy.net/2008/01/23/getting-the-hosts-main-window-handle-in-an-office-add-in/</link>
		<comments>http://esmithy.net/2008/01/23/getting-the-hosts-main-window-handle-in-an-office-add-in/#comments</comments>
		<pubDate>Wed, 23 Jan 2008 21:26:49 +0000</pubDate>
		<dc:creator>Eric</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[Office]]></category>

		<guid isPermaLink="false">http://esmithy.net/2008/01/23/getting-the-hosts-main-window-handle-in-an-office-add-in/</guid>
		<description><![CDATA[Sometimes you want the window handle of the host application when you&#8217;re writing an Office add-in. Excel includes that as a property of the Application object in newer versions of the object model, but Word and PowerPoint don&#8217;t. I seem to remember some sample code from Microsoft that suggests using FindWindow to get the handle, [...]]]></description>
			<content:encoded><![CDATA[<p>Sometimes you want the window handle of the host application when you&#8217;re writing an Office add-in. Excel includes that as a property of the Application object in newer versions of the object model, but Word and PowerPoint don&#8217;t. I seem to remember some sample code from Microsoft that suggests using FindWindow to get the handle, but that always seems problematic:</p>
<ul>
<li>You can search by class name (e.g. &#8220;OpusApp&#8221; for Word), but what if you somehow have multiple Word processes running? Which window do you get?</li>
<li>You can search by window text, but it can be really hard to figure out what the window text is.</li>
<li>You can set the Caption property on the Application object to some magic text and search for a window with the magic text, but Word throws all kinds of other stuff into the caption so this generally doesn&#8217;t work reliably.</li>
</ul>
<p>Instead, if you&#8217;re using managed code, you can just do this:</p>

<div class="wp_syntax"><div class="code"><pre class="csharp" style="font-family:monospace;">IntPtr hwnd <span style="color: #008000;">=</span> Process.<span style="color: #0000FF;">GetCurrentProcess</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>.<span style="color: #0000FF;">MainWindowHandle</span><span style="color: #008000;">;</span></pre></div></div>

<p>Underneath this uses <code>EnumWindows</code> and <code>GetWindowThreadProcessId</code> to find the right window.</p>
]]></content:encoded>
			<wfw:commentRss>http://esmithy.net/2008/01/23/getting-the-hosts-main-window-handle-in-an-office-add-in/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Why StringComparison.Ordinal Is Usually the Right Choice</title>
		<link>http://esmithy.net/2007/10/15/why-stringcomparisonordinal-is-usually-the-right-choice/</link>
		<comments>http://esmithy.net/2007/10/15/why-stringcomparisonordinal-is-usually-the-right-choice/#comments</comments>
		<pubDate>Mon, 15 Oct 2007 20:54:18 +0000</pubDate>
		<dc:creator>Eric</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Windows]]></category>

		<guid isPermaLink="false">http://esmithy.net/2007/10/15/why-stringcomparisonordinal-is-usually-the-right-choice/</guid>
		<description><![CDATA[A question that arose in response to my previous post (about how string comparisons can produce unexpected results when done in a culture-sensitive way) was Which is right, StringComparison.Ordinal or StringComparison.InvariantCulture? The short answer: StringComparison.Ordinal. There is a good article explaining the differences between the StringComparison enum values on MSDN. I&#8217;ll summarize here, but without mentioning the &#8220;IgnoreCase&#8221; variations in [...]]]></description>
			<content:encoded><![CDATA[<p>A question that arose in response to my <a href="http://esmithy.net/2007/10/11/unicode-surprises/">previous post</a> (about how string comparisons can produce unexpected results when done in a culture-sensitive way) was <em>Which is right, StringComparison.Ordinal or StringComparison.InvariantCulture?</em> The short answer: StringComparison.Ordinal.</p>
<p><span id="more-118"></span></p>
<p>There is a <a href="http://msdn2.microsoft.com/en-us/library/ms973919.aspx">good article</a> explaining the differences between the StringComparison enum values on MSDN. I&#8217;ll summarize here, but without mentioning the &#8220;IgnoreCase&#8221; variations in the enum since those are generally understood (though there are subtleties with case conversion). </p>
<p>StringComparison.Ordinal is the best choice in most cases. When specified in comparison operations, these cause a character by character comparison based strictly on the numeric value of the characters. This has a couple of advantages:</p>
<ol>
<li>It is very fast.</li>
<li>It is usually what you want.</li>
</ol>
<p>The performance benefits include not needing to do any table lookups as well as the ability to fail fast if the two string lengths are not equal.</p>
<p>It generally only makes sense to use StringComparison.CurrentCulture if you are going to display the result of the operation to the user, such as in a list where the items are supposed to be sorted alphabetically according to the user&#8217;s culture. Instead of a character by character comparison, it is a &#8220;linguistic&#8221; comparison.</p>
<p>This leaves StringComparison.InvariantCulture. The author of the MSDN article was hard pressed to come up with a good reason for using StringComparison.InvariantCulture from .NET 2.0 forward. It does a linguistic comparison, but in a way that is always the same regardless of the current culture. In other words, it isn&#8217;t a character by character comparison, but it isn&#8217;t necessarily correct for the current culture either.</p>
<p>An example clarifies things:</p>

<div class="wp_syntax"><div class="code"><pre class="csharp" style="font-family:monospace;"><span style="color: #0600FF;">static</span> <span style="color: #0600FF;">void</span> Main<span style="color: #000000;">&#40;</span><span style="color: #FF0000;">string</span><span style="color: #000000;">&#91;</span><span style="color: #000000;">&#93;</span> args<span style="color: #000000;">&#41;</span>
<span style="color: #000000;">&#123;</span>
  Console.<span style="color: #0000FF;">WriteLine</span><span style="color: #000000;">&#40;</span><span style="color: #666666;">&quot;Grüße&quot;</span>.<span style="color: #0000FF;">EndsWith</span><span style="color: #000000;">&#40;</span><span style="color: #666666;">&quot;sse&quot;</span>, StringComparison.<span style="color: #0000FF;">Ordinal</span><span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
  Console.<span style="color: #0000FF;">WriteLine</span><span style="color: #000000;">&#40;</span><span style="color: #666666;">&quot;Grüße&quot;</span>.<span style="color: #0000FF;">EndsWith</span><span style="color: #000000;">&#40;</span><span style="color: #666666;">&quot;sse&quot;</span>, StringComparison.<span style="color: #0000FF;">CurrentCulture</span><span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
  Console.<span style="color: #0000FF;">WriteLine</span><span style="color: #000000;">&#40;</span><span style="color: #666666;">&quot;Grüße&quot;</span>.<span style="color: #0000FF;">EndsWith</span><span style="color: #000000;">&#40;</span><span style="color: #666666;">&quot;sse&quot;</span>, StringComparison.<span style="color: #0000FF;">InvariantCulture</span><span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
  Console.<span style="color: #0000FF;">WriteLine</span><span style="color: #000000;">&#40;</span><span style="color: #666666;">&quot;Grüße&quot;</span>.<span style="color: #0000FF;">EndsWith</span><span style="color: #000000;">&#40;</span><span style="color: #666666;">&quot;sse&quot;</span><span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
<span style="color: #000000;">&#125;</span></pre></div></div>

<p>This example uses the German ess-szet or sharp s character. In German, ß and ss are linguistically equivalent, so the results of running the program, even using the English (United States) culture, are:</p>
<pre>False
True
True
True</pre>
<p>If a user searched a document for &#8220;Grüsse&#8221;, it would be appropriate to show matches for both &#8220;Grüsse&#8221; and &#8220;Grüße&#8221;, and so use CurrentCulture. But for most other day-to-day string manipulations within code, such as comparing file names for equivalence, you should use one of the Ordinal values.</p>
<p><img src="http://esmithy.net/content/greetings.jpg" alt="Both filenames are valid" /></p>
<p>Both are valid (and distinct) file names, after all, which is not discernible using either CurrentCulture or InvariantCulture.</p>
]]></content:encoded>
			<wfw:commentRss>http://esmithy.net/2007/10/15/why-stringcomparisonordinal-is-usually-the-right-choice/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Unicode Surprises</title>
		<link>http://esmithy.net/2007/10/11/unicode-surprises/</link>
		<comments>http://esmithy.net/2007/10/11/unicode-surprises/#comments</comments>
		<pubDate>Fri, 12 Oct 2007 03:15:33 +0000</pubDate>
		<dc:creator>Eric</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[Bafflers]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Windows]]></category>

		<guid isPermaLink="false">http://esmithy.net/2007/10/11/unicode-surprises/</guid>
		<description><![CDATA[I got a defect from QA today saying that our product was unable to track files in paths containing Unicode characters. I&#8217;ll admit that I was skeptical. I had just tried that myself the other day and it worked perfectly. Trying it again today also worked perfectly, but the QA engineer showed me otherwise. The path [...]]]></description>
			<content:encoded><![CDATA[<p>I got a defect from QA today saying that our product was unable to track files in paths containing Unicode characters. I&#8217;ll admit that I was skeptical. I had just tried that myself the other day and it worked perfectly. Trying it again today also worked perfectly, but the QA engineer showed me otherwise.</p>
<p><span id="more-117"></span></p>
<p>The path with the problem was something like this: <code>\\qa\tests\۩۩۩۩۩</code></p>
<p> The unusual character there is the Arabic symbol &#8220;Place of Sajdah&#8221; (U+06E9). For some reason, this path didn&#8217;t work correctly.</p>
<p>Ultimately, I tracked the problem down to a bit of code that was trying to test whether the path ended with a separator character, and if not, add one. It looked like this.</p>

<div class="wp_syntax"><div class="code"><pre class="csharp" style="font-family:monospace;"><span style="color: #0600FF;">if</span> <span style="color: #000000;">&#40;</span><span style="color: #008000;">!</span>path.<span style="color: #0000FF;">EndsWith</span><span style="color: #000000;">&#40;</span>Path.<span style="color: #0000FF;">DirectorySeparatorChar</span>.<span style="color: #0000FF;">ToString</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span>
<span style="color: #000000;">&#123;</span>
    path <span style="color: #008000;">+=</span> Path.<span style="color: #0000FF;">DirectorySeparatorChar</span><span style="color: #008000;">;</span>
<span style="color: #000000;">&#125;</span></pre></div></div>

<p>This code wasn&#8217;t working as expected, so when the path was combined (using string concatenation) with a file name, the path separator was missing, which lead to the final symptom described by the defect. There are a couple of problems with this code.</p>
<ol>
<li><code>System.IO.Path.Combine</code> is the right way to merge paths where possible &#8212; you shouldn&#8217;t have to worry about whether there is a trailing slash or not</li>
<li>The simplest form of <code>EndsWith</code> (and <code>StartsWith</code>) doesn&#8217;t work as expected with roughly 20% of Unicode characters</li>
</ol>
<p><a href="http://blogs.msdn.com/michkap/archive/2005/01/18/355210.aspx">Michael Kaplan explains</a> that this is because many Unicode characters don&#8217;t have entries in the Windows sorting weight tables, and are therefore effectively invisible for some comparisons.</p>
<p>Surprisingly, <code>@"\\qa\tests\۩۩۩۩۩".EndsWith(@"\")</code> evaluates to <code>true</code>. All of the Place of Sajdah characters are &#8220;invisible&#8221; in terms of weight, and once you realize that, then <em>obviously</em> the string ends with a backslash. Also surprising is that all strings start with &#8220;۩&#8221;. That is, <code>"Cheese".StartsWith("۩")</code> evaluates to <code>true</code>. The <code>string.Equals</code> method and operator don&#8217;t have this problem, though, because they compare lengths before ever getting to the part where the Place of Sajdah characters would be thrown out of &#8220;۩۩۩Monkey۩۩۩&#8221; and thus become equal to &#8220;Monkey&#8221;.</p>
<p>The way to fix the problem is to use either <code>StringComparison.Ordinal</code> or <code>StringComparison.OrdinalIgnoreCase</code> in the call to <code>StartsWith</code> or <code>EndsWith</code>. So the code snippet from above would work as expected when modified as follows:</p>

<div class="wp_syntax"><div class="code"><pre class="csharp" style="font-family:monospace;"><span style="color: #0600FF;">if</span> <span style="color: #000000;">&#40;</span><span style="color: #008000;">!</span>path.<span style="color: #0000FF;">EndsWith</span><span style="color: #000000;">&#40;</span>Path.<span style="color: #0000FF;">DirectorySeparatorChar</span>.<span style="color: #0000FF;">ToString</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>, StringComparison.<span style="color: #0000FF;">OrdinalIgnoreCase</span><span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span>
<span style="color: #000000;">&#123;</span>
    path <span style="color: #008000;">+=</span> Path.<span style="color: #0000FF;">DirectorySeparatorChar</span><span style="color: #008000;">;</span>
<span style="color: #000000;">&#125;</span></pre></div></div>

]]></content:encoded>
			<wfw:commentRss>http://esmithy.net/2007/10/11/unicode-surprises/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
