<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://msmvps.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Jon Skeet: Coding Blog : Stack Overflow</title><link>http://msmvps.com/blogs/jon_skeet/archive/tags/Stack+Overflow/default.aspx</link><description>Tags: Stack Overflow</description><dc:language>en</dc:language><generator>CommunityServer 2008.5 SP2 (Build: 40407.4157)</generator><item><title>"Magic" null argument testing</title><link>http://msmvps.com/blogs/jon_skeet/archive/2009/12/09/quot-magic-quot-null-argument-testing.aspx</link><pubDate>Wed, 09 Dec 2009 18:04:47 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1744445</guid><dc:creator>skeet</dc:creator><slash:comments>49</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/jon_skeet/rsscomments.aspx?PostID=1744445</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/jon_skeet/commentapi.aspx?PostID=1744445</wfw:comment><comments>http://msmvps.com/blogs/jon_skeet/archive/2009/12/09/quot-magic-quot-null-argument-testing.aspx#comments</comments><description>&lt;p&gt;Warning: here be dragons. I don&amp;#39;t think this is the right way to check for null arguments, but it was an intriguing idea.&lt;/p&gt;  &lt;p&gt;Today on Stack Overflow, I answered a &lt;a href="http://stackoverflow.com/questions/1873264"&gt;question about checking null arguments&lt;/a&gt;. The questioner was already using an extension similar to my own one in &lt;a href="http://pobox.com/~skeet/csharp/miscutil"&gt;MiscUtil&lt;/a&gt;, allowing code like this:&lt;/p&gt;  &lt;div class="code"&gt;&lt;span class="Modifier"&gt;public&lt;/span&gt;&amp;#160;&lt;span class="ValueType"&gt;void&lt;/span&gt; DoSomething(&lt;span class="ReferenceType"&gt;string&lt;/span&gt; name)     &lt;br /&gt;{     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; name.ThrowIfNull(&lt;span class="String"&gt;&amp;quot;name&amp;quot;&lt;/span&gt;);     &lt;br /&gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="InlineComment"&gt;// Normal code here&lt;/span&gt;     &lt;br /&gt;} &lt;/div&gt;  &lt;p&gt;That&amp;#39;s all very well, but it&amp;#39;s annoying to have to repeat the &lt;code&gt;name&lt;/code&gt; part. Now in an ideal world, I&amp;#39;d say it would be nice to add an attribute to the parameter and have the check performed automatically (and when PostSharp works with .NET 4.0, I&amp;#39;m going to give that a go, mixing Code Contracts and AOP…) – but for the moment, how far can we go with extension methods?&lt;/p&gt;  &lt;p&gt;I stand by my answer from that question – the code above is the simplest way to achieve the goal for the moment… but another answer raised the interesting prospect of combining anonymous types, extension methods, generics, reflection and manually-created expression trees. Now that&amp;#39;s a recipe for hideous code… but it actually works.&lt;/p&gt;  &lt;p&gt;The idea is to allow code like this:&lt;/p&gt;  &lt;div class="code"&gt;&lt;span class="Modifier"&gt;public&lt;/span&gt;&amp;#160;&lt;span class="ValueType"&gt;void&lt;/span&gt; DoSomething(&lt;span class="ReferenceType"&gt;string&lt;/span&gt; name, &lt;span class="ReferenceType"&gt;string&lt;/span&gt; canBeNull, &lt;span class="ValueType"&gt;int&lt;/span&gt; foo, Stream input)     &lt;br /&gt;{     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Keyword"&gt;new&lt;/span&gt; { name, input }.CheckNotNull();     &lt;br /&gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="InlineComment"&gt;// Normal code here&lt;/span&gt;     &lt;br /&gt;} &lt;/div&gt;  &lt;p&gt;That should check &lt;code&gt;name&lt;/code&gt; and &lt;code&gt;input&lt;/code&gt;, in that order, and throw an appropriate &lt;code&gt;ArgumentNullException&lt;/code&gt; - including parameter name - if one of them is null. It uses the fact that projection initializers in anonymous types use the primary expression&amp;#39;s name as the property name in the generated type, and the value of that expression ends up in the instance. Therefore, given an instance of the anonymous type initializer like the above, we have both the name and value despite having only typed it in once.&lt;/p&gt;  &lt;p&gt;Now obviously this &lt;em&gt;could&lt;/em&gt; be done with normal reflection – but that we be slow as heck. No, we want to effectively find the properties &lt;em&gt;once&lt;/em&gt;, and generate strongly typed delegates to perform the property access. That sounds like a job for &lt;a href="http://msdn.microsoft.com/en-us/library/system.delegate.createdelegate.aspx"&gt;Delegate.CreateDelegate&lt;/a&gt;, but it&amp;#39;s not quite that simple… to create the delegate, we&amp;#39;d need to know (at compile time) what the property type is. We could do that with another generic type, but we can do better than that. All we really need to know about the value is whether or not it&amp;#39;s null. So given a &amp;quot;container&amp;quot; type &lt;code&gt;T&lt;/code&gt;, we&amp;#39;d like a bunch of delegates, one for each property, returning whether that property is null for a specified instance – i.e. a &lt;code&gt;Func&amp;lt;T, bool&amp;gt;&lt;/code&gt;. And how do we build delegates at execution time with custom logic? We use expression trees…&lt;/p&gt;  &lt;p&gt;I&amp;#39;ve now implemented this, along with a brief set of unit tests. The irony is that the tests took longer than the implementation (which isn&amp;#39;t very unusual) – and so did writing it up in this blog post. I&amp;#39;m not saying that it couldn&amp;#39;t be improved (and indeed in .NET 4.0 I could probably make the delegate throw the relevant exception itself) but it works! I haven&amp;#39;t benchmarked it, but I&amp;#39;d expect it to be nearly as fast as manual tests – insignificant in methods that do real work. (The same wouldn&amp;#39;t be true using reflection every time, of course.)&lt;/p&gt;  &lt;p&gt;The full project including test cases is &lt;a href="http://pobox.com/~skeet/csharp/blogfiles/NullMagic.zip"&gt;now available&lt;/a&gt;, but here&amp;#39;s the (almost completely uncommented) &amp;quot;production&amp;quot; code.&lt;/p&gt;  &lt;div class="code"&gt;&lt;span class="Namespace"&gt;using&lt;/span&gt; System;    &lt;br /&gt;&lt;span class="Namespace"&gt;using&lt;/span&gt; System.Collections.Generic;    &lt;br /&gt;&lt;span class="Namespace"&gt;using&lt;/span&gt; System.Linq;    &lt;br /&gt;&lt;span class="Namespace"&gt;using&lt;/span&gt; System.Reflection;    &lt;br /&gt;&lt;span class="Namespace"&gt;using&lt;/span&gt; System.Linq.Expressions;    &lt;br /&gt;    &lt;br /&gt;&lt;span class="Modifier"&gt;public&lt;/span&gt;&amp;#160;&lt;span class="Modifier"&gt;static&lt;/span&gt;&amp;#160;&lt;span class="ReferenceType"&gt;class&lt;/span&gt; Extensions    &lt;br /&gt;{    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Modifier"&gt;public&lt;/span&gt;&amp;#160;&lt;span class="Modifier"&gt;static&lt;/span&gt;&amp;#160;&lt;span class="ValueType"&gt;void&lt;/span&gt; CheckNotNull&amp;lt;T&amp;gt;(&lt;span class="Keyword"&gt;this&lt;/span&gt; T container) &lt;span class="Linq"&gt;where&lt;/span&gt; T : &lt;span class="ReferenceType"&gt;class&lt;/span&gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Statement"&gt;if&lt;/span&gt; (container == &lt;span class="Keyword"&gt;null&lt;/span&gt;)    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Statement"&gt;throw&lt;/span&gt;&amp;#160;&lt;span class="Keyword"&gt;new&lt;/span&gt; ArgumentNullException(&lt;span class="String"&gt;&amp;quot;container&amp;quot;&lt;/span&gt;);    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; NullChecker&amp;lt;T&amp;gt;.Check(container);    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }    &lt;br /&gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Modifier"&gt;private&lt;/span&gt;&amp;#160;&lt;span class="Modifier"&gt;static&lt;/span&gt;&amp;#160;&lt;span class="ReferenceType"&gt;class&lt;/span&gt; NullChecker&amp;lt;T&amp;gt; &lt;span class="Linq"&gt;where&lt;/span&gt; T : &lt;span class="ReferenceType"&gt;class&lt;/span&gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Modifier"&gt;private&lt;/span&gt;&amp;#160;&lt;span class="Modifier"&gt;static&lt;/span&gt;&amp;#160;&lt;span class="Modifier"&gt;readonly&lt;/span&gt; List&amp;lt;Func&amp;lt;T, &lt;span class="ValueType"&gt;bool&lt;/span&gt;&amp;gt;&amp;gt; checkers;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Modifier"&gt;private&lt;/span&gt;&amp;#160;&lt;span class="Modifier"&gt;static&lt;/span&gt;&amp;#160;&lt;span class="Modifier"&gt;readonly&lt;/span&gt; List&amp;lt;&lt;span class="ReferenceType"&gt;string&lt;/span&gt;&amp;gt; names;    &lt;br /&gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Modifier"&gt;static&lt;/span&gt; NullChecker()    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; checkers = &lt;span class="Keyword"&gt;new&lt;/span&gt; List&amp;lt;Func&amp;lt;T, &lt;span class="ValueType"&gt;bool&lt;/span&gt;&amp;gt;&amp;gt;();    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; names = &lt;span class="Keyword"&gt;new&lt;/span&gt; List&amp;lt;&lt;span class="ReferenceType"&gt;string&lt;/span&gt;&amp;gt;();    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="InlineComment"&gt;// We can&amp;#39;t rely on the order of the properties, but we&lt;/span&gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="InlineComment"&gt;// can rely on the order of the constructor parameters&lt;/span&gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="InlineComment"&gt;// in an anonymous type - and that there&amp;#39;ll only be&lt;/span&gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="InlineComment"&gt;// one constructor.&lt;/span&gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Statement"&gt;foreach&lt;/span&gt; (&lt;span class="ReferenceType"&gt;string&lt;/span&gt; name &lt;span class="Statement"&gt;in&lt;/span&gt;&amp;#160;&lt;span class="Keyword"&gt;typeof&lt;/span&gt;(T).GetConstructors()[0]    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; .GetParameters()    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; .Select(p =&amp;gt; p.Name))    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; names.Add(name);    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; PropertyInfo property = &lt;span class="Keyword"&gt;typeof&lt;/span&gt;(T).GetProperty(name);    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="InlineComment"&gt;// I&amp;#39;ve omitted a lot of error checking, but here&amp;#39;s&lt;/span&gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="InlineComment"&gt;// at least one bit...&lt;/span&gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Statement"&gt;if&lt;/span&gt; (property.PropertyType.IsValueType)    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Statement"&gt;throw&lt;/span&gt;&amp;#160;&lt;span class="Keyword"&gt;new&lt;/span&gt; ArgumentException    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; (&lt;span class="String"&gt;&amp;quot;Property &amp;quot;&lt;/span&gt; + property + &lt;span class="String"&gt;&amp;quot; is a value type&amp;quot;&lt;/span&gt;);    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ParameterExpression param = Expression.Parameter(&lt;span class="Keyword"&gt;typeof&lt;/span&gt;(T), &lt;span class="String"&gt;&amp;quot;container&amp;quot;&lt;/span&gt;);    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Expression propertyAccess = Expression.Property(param, property);    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Expression nullValue = Expression.Constant(&lt;span class="Keyword"&gt;null&lt;/span&gt;, property.PropertyType);    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Expression equality = Expression.Equal(propertyAccess, nullValue);    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Linq"&gt;var&lt;/span&gt; lambda = Expression.Lambda&amp;lt;Func&amp;lt;T, &lt;span class="ValueType"&gt;bool&lt;/span&gt;&amp;gt;&amp;gt;(equality, param);    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; checkers.Add(lambda.Compile());    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }    &lt;br /&gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Modifier"&gt;internal&lt;/span&gt;&amp;#160;&lt;span class="Modifier"&gt;static&lt;/span&gt;&amp;#160;&lt;span class="ValueType"&gt;void&lt;/span&gt; Check(T item)    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Statement"&gt;for&lt;/span&gt; (&lt;span class="ValueType"&gt;int&lt;/span&gt; i = 0; i &amp;lt; checkers.Count; i++)    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Statement"&gt;if&lt;/span&gt; (checkers[i](item))    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Statement"&gt;throw&lt;/span&gt;&amp;#160;&lt;span class="Keyword"&gt;new&lt;/span&gt; ArgumentNullException(names[i]);    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }    &lt;br /&gt;} &lt;/div&gt;  &lt;p&gt;Oh, and just as a miracle – the expression tree worked first time. I&amp;#39;m no Marc Gravell, but I&amp;#39;m clearly improving :)&lt;/p&gt;  &lt;p&gt;&lt;b&gt;Update:&lt;/b&gt; Marc Gravell pointed out that the order of the results of &lt;code&gt;Type.GetProperties&lt;/code&gt; isn&amp;#39;t guaranteed - something I should have remembered myself. However, the order of the constructor parameters &lt;i&gt;will&lt;/i&gt; be the same as in the anonymous type initialization expression, so I&amp;#39;ve updated the code above to reflect that. Marc also showed how it could almost all be put into a single expression tree which returns either null (for no error) or the name of the &amp;quot;failing&amp;quot; parameter. Very clever :) &lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1744445" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/Wacky+Ideas/default.aspx">Wacky Ideas</category><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/Stack+Overflow/default.aspx">Stack Overflow</category><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/Evil+Code/default.aspx">Evil Code</category></item><item><title>Just how spiky is your traffic?</title><link>http://msmvps.com/blogs/jon_skeet/archive/2009/11/16/just-how-spiky-is-your-traffic.aspx</link><pubDate>Mon, 16 Nov 2009 19:48:19 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1740046</guid><dc:creator>skeet</dc:creator><slash:comments>14</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/jon_skeet/rsscomments.aspx?PostID=1740046</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/jon_skeet/commentapi.aspx?PostID=1740046</wfw:comment><comments>http://msmvps.com/blogs/jon_skeet/archive/2009/11/16/just-how-spiky-is-your-traffic.aspx#comments</comments><description>&lt;p&gt;No, this isn&amp;#39;t the post about dynamic languages I promise. That will come soon. This is just a quick interlude. This afternoon, while answering a question on Stack Overflow&lt;sup&gt;1&lt;/sup&gt; about the difference between using an array and a Dictionary&amp;lt;string, string&amp;gt; (where each string was actually the string representation of an integer) I posted the usual spiel about preferring readable code to micro-optimisation. The response in a comment - about the performance aspect - was:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;Well that&amp;#39;s not so easily said for a .com where performance on a site that receives about 1 million hits a month relies on every little ounce of efficiency gains you can give it.&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;A million hits a month, eh? That sounds quite impressive, until you actually break it down. Let&amp;#39;s take a month of 30 days - that has 30 * 24 * 60 * 60 = 2,592,000 seconds&lt;sup&gt;2&lt;/sup&gt;. In other words, a million hits a month is less than one hit every two seconds. Not so impressive. At Google we tend to measure traffic in QPS (queries per second, even if they&amp;#39;re not really queries - the search terminology becomes pervasive) so this is around 0.39 QPS. Astonished that someone would make such a claim in favour of micro-optimisation at that traffic level, I &lt;a href="http://twitter.com/jonskeet/status/5767353745"&gt;tweeted about it&lt;/a&gt;. Several of the replies were along the lines of &amp;quot;yeah, but traffic&amp;#39;s not evenly distributed.&amp;quot; That&amp;#39;s entirely true. Let&amp;#39;s see how high we can make the traffic without going absurd though.&lt;/p&gt;  &lt;p&gt;Let&amp;#39;s suppose this is a site which is only relevant on weekdays - that cuts us down to 20 days in the month. Now let&amp;#39;s suppose it&amp;#39;s only relevant for one hour per day - it&amp;#39;s something people look at when they get to work, and most of the users are in one time zone. That&amp;#39;s a pretty massive way of spiking. We&amp;#39;ve gone down from 30 full days of traffic to 20 hours - or 20 * 60 * 60 = 72000 seconds, giving 14 QPS. Heck, let&amp;#39;s say the peak of the spike is double that - a whopping 28 QPS.&lt;/p&gt;  &lt;p&gt;Three points about this:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;28 QPS is still not a huge amount of traffic.&lt;/li&gt;    &lt;li&gt;If you&amp;#39;re &lt;em&gt;really&lt;/em&gt; interested in handling peak traffic of ~28 QPS without latency becoming huge, it&amp;#39;s worth quoting &lt;em&gt;that&lt;/em&gt; figure rather than &amp;quot;a million hits a month&amp;quot; because the latter is somewhat irrelevant, and causes us to make wild (and probably wildly inaccurate) guesses about your load distribution.&lt;/li&gt;    &lt;li&gt;If you&amp;#39;re going to bring the phrase &amp;quot;a .com&amp;quot; into the picture, attempting to make it sound particularly important, you really shouldn&amp;#39;t be thinking about hosting your web site on one server - so the QPS gets diluted again.&lt;/li&gt;    &lt;li&gt;Even at 28 QPS, the sort of difference that would be made here is tiny. A quick microbenchmark (with all the associated caveats) showed that on my laptop (hardly a server-class machine) I could build the dictionary and index into it 3 times 2.8 &lt;em&gt;million&lt;/em&gt; times in about 5 seconds. If every request needed to do that 100 times, then the cost of doing it 28 requests per second on my laptop would still only be 0.5% of that second - not a really significant benefit, despite the hugely exaggerated estimates of how often we needed to do that.&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;There are various other ways in which it&amp;#39;s not a great piece of code, but the charge against premature optimization still stands. You &lt;em&gt;don&amp;#39;t&lt;/em&gt; need to get every little ounce of efficiency out of your code. Chances are, if you start guessing at where you can get efficiency, you&amp;#39;re going to be wrong. Measure, measure, measure - profile, profile, profile. Once you&amp;#39;ve done all of that and proved that a change reducing clarity has a significant benefit, go for it - but until then, write the most readable code you can. Likewise work out your performance goals in a &lt;em&gt;meaningful&lt;/em&gt; fashion before you worry too much - and hits per months isn&amp;#39;t a meaningful figure.&lt;/p&gt;  &lt;p&gt;Performance is important - too important to be guessed about instead of measured.&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;hr /&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;sup&gt;1&lt;/sup&gt; I&amp;#39;m not linking to it because the Streisand effect would render this question more important than it really is. I&amp;#39;m sure you can find it if you really want to, but that&amp;#39;s not the point of the post.&lt;/p&gt;  &lt;p&gt;&lt;sup&gt;2&lt;/sup&gt; Anyone who wants to nitpick and talk about months which are a bit longer or shorter than that due to daylight saving time changes (despite still being 30 days) can implement that logic for me in Noda Time.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1740046" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/General/default.aspx">General</category><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/Stack+Overflow/default.aspx">Stack Overflow</category></item><item><title>Revisiting randomness</title><link>http://msmvps.com/blogs/jon_skeet/archive/2009/11/04/revisiting-randomness.aspx</link><pubDate>Wed, 04 Nov 2009 07:40:15 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1737577</guid><dc:creator>skeet</dc:creator><slash:comments>18</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/jon_skeet/rsscomments.aspx?PostID=1737577</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/jon_skeet/commentapi.aspx?PostID=1737577</wfw:comment><comments>http://msmvps.com/blogs/jon_skeet/archive/2009/11/04/revisiting-randomness.aspx#comments</comments><description>&lt;p&gt;Almost every Stack Overflow question which includes the words &amp;quot;random&amp;quot; and &amp;quot;repeated&amp;quot; has the same basic answer. It&amp;#39;s one of the most common &amp;quot;gotchas&amp;quot; in .NET, Java, and no doubt other platforms: creating a new random number generator without specifying a seed will depend on the current instant of time. The current time as measured by the computer doesn&amp;#39;t change very often compared with how often you can create and use a random number generator – so code which repeatedly creates a new instance of Random and uses it once will end up showing a lot of repetition.&lt;/p&gt;  &lt;p&gt;One common solution is to use a static field to store a single instance of Random and reuse it. That&amp;#39;s okay in Java (where Random is thread-safe) but it&amp;#39;s not so good in .NET – if you use the same instance repeatedly from .NET, you can corrupt the internal data structures.&lt;/p&gt;  &lt;p&gt;A long time ago, I created a &lt;a href="http://pobox.com/~skeet/csharp/miscutil/usage/staticrandom.html"&gt;StaticRandom class&lt;/a&gt; in &lt;a href="http://pobox.com/~skeet/csharp/miscutil"&gt;MiscUtil&lt;/a&gt; – essentially, it was just a bunch of static methods (to mirror the instance methods found in Random) wrapping a single instance of Random and locking appropriately. This allows you to just call StaticRandom.Next(1, 7) to roll a die, for example. However, it has a couple of problems:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;It doesn&amp;#39;t scale well in a multi-threaded environment. When I originally wrote it, I benchmarked an alternative approach using [ThreadStatic] and at the time, locking won (at least on my computer, which may well have only had a single core). &lt;/li&gt;    &lt;li&gt;It doesn&amp;#39;t provide any way of getting at an instance of Random, other than by using new Random(StaticRandom.Next()). &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;The latter point is mostly a problem because it encourages a style of coding where you just use StaticRandom.Next(…) any time you want a random number. This is undoubtedly convenient in some situations, but it goes against the idea of &lt;a href="http://stackoverflow.com/questions/1667516/doesnt-passing-in-parameters-that-should-be-known-implicitly-violate-encapsulati/1667590#1667590"&gt;treating a source of randomness as a service or dependency&lt;/a&gt;. It makes it harder to get repeatability and to see what needs that dependency.&lt;/p&gt;  &lt;p&gt;I could have just added a method generating a new instance into the existing class, but I decided to play with a different approach – going back to per-thread instances, but this time using the &lt;a href="http://msdn.microsoft.com/en-us/library/dd642243(VS.100).aspx"&gt;ThreadLocal&amp;lt;T&amp;gt; class&lt;/a&gt; introduced in .NET 4.0. Here&amp;#39;s the resulting code:&lt;/p&gt;  &lt;div class="code"&gt;&lt;span class="Namespace"&gt;using&lt;/span&gt; System;     &lt;br /&gt;&lt;span class="Namespace"&gt;using&lt;/span&gt; System.Threading;     &lt;br /&gt;    &lt;br /&gt;&lt;span class="Namespace"&gt;namespace&lt;/span&gt; RandomDemo     &lt;br /&gt;{     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="XmlComment"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="XmlComment"&gt;/// Convenience class for dealing with randomness.&lt;/span&gt;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="XmlComment"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Modifier"&gt;public&lt;/span&gt;&amp;#160;&lt;span class="Modifier"&gt;static&lt;/span&gt;&amp;#160;&lt;span class="ReferenceType"&gt;class&lt;/span&gt; ThreadLocalRandom     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="XmlComment"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="XmlComment"&gt;/// Random number generator used to generate seeds,&lt;/span&gt;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="XmlComment"&gt;/// which are then used to create new random number&lt;/span&gt;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="XmlComment"&gt;/// generators on a per-thread basis.&lt;/span&gt;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="XmlComment"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Modifier"&gt;private&lt;/span&gt;&amp;#160;&lt;span class="Modifier"&gt;static&lt;/span&gt;&amp;#160;&lt;span class="Modifier"&gt;readonly&lt;/span&gt; Random globalRandom = &lt;span class="Keyword"&gt;new&lt;/span&gt; Random();     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Modifier"&gt;private&lt;/span&gt;&amp;#160;&lt;span class="Modifier"&gt;static&lt;/span&gt;&amp;#160;&lt;span class="Modifier"&gt;readonly&lt;/span&gt;&amp;#160;&lt;span class="ReferenceType"&gt;object&lt;/span&gt; globalLock = &lt;span class="Keyword"&gt;new&lt;/span&gt;&amp;#160;&lt;span class="ReferenceType"&gt;object&lt;/span&gt;();     &lt;br /&gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="XmlComment"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="XmlComment"&gt;/// Random number generator &lt;/span&gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="XmlComment"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Modifier"&gt;private&lt;/span&gt;&amp;#160;&lt;span class="Modifier"&gt;static&lt;/span&gt;&amp;#160;&lt;span class="Modifier"&gt;readonly&lt;/span&gt; ThreadLocal&amp;lt;Random&amp;gt; threadRandom = &lt;span class="Keyword"&gt;new&lt;/span&gt; ThreadLocal&amp;lt;Random&amp;gt;(NewRandom);     &lt;br /&gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="XmlComment"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="XmlComment"&gt;/// Creates a new instance of Random. The seed is derived &lt;/span&gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="XmlComment"&gt;/// from a global (static) instance of Random, rather &lt;/span&gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="XmlComment"&gt;/// than time.&lt;/span&gt;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="XmlComment"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Modifier"&gt;public&lt;/span&gt;&amp;#160;&lt;span class="Modifier"&gt;static&lt;/span&gt; Random NewRandom()     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Statement"&gt;lock&lt;/span&gt; (globalLock)     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Statement"&gt;return&lt;/span&gt;&amp;#160;&lt;span class="Keyword"&gt;new&lt;/span&gt; Random(globalRandom.Next());     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }     &lt;br /&gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="XmlComment"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="XmlComment"&gt;/// Returns an instance of Random which can be used freely&lt;/span&gt;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="XmlComment"&gt;/// within the current thread.&lt;/span&gt;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="XmlComment"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Modifier"&gt;public&lt;/span&gt;&amp;#160;&lt;span class="Modifier"&gt;static&lt;/span&gt; Random Instance { get { &lt;span class="Statement"&gt;return&lt;/span&gt; threadRandom.Value; } }     &lt;br /&gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="XmlComment"&gt;/// &amp;lt;summary&amp;gt;See &amp;lt;see cref=&amp;quot;Random.Next()&amp;quot; /&amp;gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Modifier"&gt;public&lt;/span&gt;&amp;#160;&lt;span class="Modifier"&gt;static&lt;/span&gt;&amp;#160;&lt;span class="ValueType"&gt;int&lt;/span&gt; Next()     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Statement"&gt;return&lt;/span&gt; Instance.Next();     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }     &lt;br /&gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="XmlComment"&gt;/// &amp;lt;summary&amp;gt;See &amp;lt;see cref=&amp;quot;Random.Next(int)&amp;quot; /&amp;gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Modifier"&gt;public&lt;/span&gt;&amp;#160;&lt;span class="Modifier"&gt;static&lt;/span&gt;&amp;#160;&lt;span class="ValueType"&gt;int&lt;/span&gt; Next(&lt;span class="ValueType"&gt;int&lt;/span&gt; maxValue)     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Statement"&gt;return&lt;/span&gt; Instance.Next(maxValue);     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }     &lt;br /&gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="XmlComment"&gt;/// &amp;lt;summary&amp;gt;See &amp;lt;see cref=&amp;quot;Random.Next(int, int)&amp;quot; /&amp;gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Modifier"&gt;public&lt;/span&gt;&amp;#160;&lt;span class="Modifier"&gt;static&lt;/span&gt;&amp;#160;&lt;span class="ValueType"&gt;int&lt;/span&gt; Next(&lt;span class="ValueType"&gt;int&lt;/span&gt; minValue, &lt;span class="ValueType"&gt;int&lt;/span&gt; maxValue)     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Statement"&gt;return&lt;/span&gt; Instance.Next(minValue, maxValue);     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }     &lt;br /&gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="XmlComment"&gt;/// &amp;lt;summary&amp;gt;See &amp;lt;see cref=&amp;quot;Random.NextDouble()&amp;quot; /&amp;gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Modifier"&gt;public&lt;/span&gt;&amp;#160;&lt;span class="Modifier"&gt;static&lt;/span&gt;&amp;#160;&lt;span class="ValueType"&gt;double&lt;/span&gt; NextDouble()     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Statement"&gt;return&lt;/span&gt; Instance.NextDouble();     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }     &lt;br /&gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="XmlComment"&gt;/// &amp;lt;summary&amp;gt;See &amp;lt;see cref=&amp;quot;Random.NextBytes(byte[])&amp;quot; /&amp;gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Modifier"&gt;public&lt;/span&gt;&amp;#160;&lt;span class="Modifier"&gt;static&lt;/span&gt;&amp;#160;&lt;span class="ValueType"&gt;void&lt;/span&gt; NextBytes(&lt;span class="ValueType"&gt;byte&lt;/span&gt;[] buffer)     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Instance.NextBytes(buffer);     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }     &lt;br /&gt;} &lt;/div&gt;  &lt;p&gt;The user can still call the static Next(…) methods if they want, but they can also get at the thread-local instance of Random by calling ThreadLocalRandom.Instance – or easily create a new instance with ThreadLocalRandom.NewRandom(). (The fact that NewRandom uses the global instance rather than the thread-local one is an implementation detail really; it happens to be convenient from the point of view of the ThreadLocal&amp;lt;T&amp;gt; constructor. It wouldn&amp;#39;t be terribly hard to change this.)&lt;/p&gt;  &lt;p&gt;Now it&amp;#39;s easy to write a method which needs randomness (e.g. to shuffle a deck of cards) and give it a Random parameter, then call it using the thread-local instance:&lt;/p&gt;  &lt;div class="code"&gt;&lt;span class="Modifier"&gt;public&lt;/span&gt;&amp;#160;&lt;span class="ValueType"&gt;void&lt;/span&gt; Shuffle(Random rng)     &lt;br /&gt;{     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; ...     &lt;br /&gt;}     &lt;br /&gt;...     &lt;br /&gt;deck.Shuffle(ThreadLocalRandom.Instance); &lt;/div&gt;  &lt;p&gt;The Shuffle method is then easier to test and debug, and expresses its dependency explicitly.&lt;/p&gt;  &lt;h3&gt;Performance&lt;/h3&gt;  &lt;p&gt;I tested the &amp;quot;old&amp;quot; and &amp;quot;new&amp;quot; implementations in a very simple way – for varying numbers of threads, I called Next() a fixed number of times (from each thread) and timed how long it took for all the threads to finish. I&amp;#39;ve also tried a .NET-3.5-compatible version using ThreadStatic instead of ThreadLocal&amp;lt;T&amp;gt;, and running the original code and the ThreadStatic version on .NET 3.5 as well.&lt;/p&gt;  &lt;table border="1" cellspacing="0" cellpadding="2"&gt;&lt;tbody&gt;     &lt;tr&gt;       &lt;td align="right"&gt;Threads&lt;/td&gt;        &lt;td align="right"&gt;StaticRandom (4.0b2)&lt;/td&gt;        &lt;td align="right"&gt;ThreadLocalRandom (4.0b2)&lt;/td&gt;        &lt;td align="right"&gt;ThreadStaticRandom (4.0b2)&lt;/td&gt;        &lt;td align="right"&gt;StaticRandom(3.5)&lt;/td&gt;        &lt;td align="right"&gt;ThreadStaticRandom (3.5)&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td align="right"&gt;1&lt;/td&gt;        &lt;td align="right"&gt;11582&lt;/td&gt;        &lt;td align="right"&gt;6016&lt;/td&gt;        &lt;td align="right"&gt;10150&lt;/td&gt;        &lt;td align="right"&gt;10373&lt;/td&gt;        &lt;td align="right"&gt;16049&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td align="right"&gt;2&lt;/td&gt;        &lt;td align="right"&gt;24667&lt;/td&gt;        &lt;td align="right"&gt;7214&lt;/td&gt;        &lt;td align="right"&gt;9043&lt;/td&gt;        &lt;td align="right"&gt;25062&lt;/td&gt;        &lt;td align="right"&gt;17257&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td align="right"&gt;3&lt;/td&gt;        &lt;td align="right"&gt;38095&lt;/td&gt;        &lt;td align="right"&gt;10295&lt;/td&gt;        &lt;td align="right"&gt;14771&lt;/td&gt;        &lt;td align="right"&gt;36827&lt;/td&gt;        &lt;td align="right"&gt;25625&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td align="right"&gt;4&lt;/td&gt;        &lt;td align="right"&gt;49402&lt;/td&gt;        &lt;td align="right"&gt;13435&lt;/td&gt;        &lt;td align="right"&gt;19116&lt;/td&gt;        &lt;td align="right"&gt;47882&lt;/td&gt;        &lt;td align="right"&gt;34415&lt;/td&gt;     &lt;/tr&gt;   &lt;/tbody&gt;&lt;/table&gt;  &lt;p&gt;A few things to take away from this:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;The numbers were slightly erratic; somehow it was quicker to do twice the work with ThreadStaticRandom on .NET 4.0b2! This isn&amp;#39;t the perfect benchmarking machine; we&amp;#39;re interested in trends rather than absolute figures. &lt;/li&gt;    &lt;li&gt;Locking hasn&amp;#39;t changed much in performance between framework versions &lt;/li&gt;    &lt;li&gt;ThreadStatic has improved &lt;em&gt;massively&lt;/em&gt; between .NET 3.5 and 4.0 &lt;/li&gt;    &lt;li&gt;Even on 3.5, ThreadStatic wins over a global lock as soon as there&amp;#39;s contention &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;The only downside to the ThreadLocal&amp;lt;T&amp;gt; version is that it requires .NET 4.0 - but the ThreadStatic version works pretty well too.&lt;/p&gt;  &lt;p&gt;It&amp;#39;s worth bearing in mind that of course this is testing the highly unusual situation where there&amp;#39;s a &lt;em&gt;lot&lt;/em&gt; of contention in the global lock version. The performance difference in the single-threaded version where the lock is always uncontended is still present, but very small.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Update&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;After reading the comments and thinking further, I would indeed get rid of the static methods elsewhere. Also, for the purposes of dependency injection, I agree that it&amp;#39;s a good idea to have a factory interface &lt;em&gt;where that&amp;#39;s not overkill&lt;/em&gt;. The factory implementation could use either the ThreadLocal or ThreadStatic implementations, or effectively use the global lock version (by having its own instance of Random and a lock). In many cases I&amp;#39;d regard that as overkill, however.&lt;/p&gt;  &lt;p&gt;One other interesting option would be to create a thread-safe instance of Random to start with, which delegated to thread-local &amp;quot;normal&amp;quot; implementations. That would be very useful from a DI standpoint.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1737577" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/Parallelisation/default.aspx">Parallelisation</category><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/Stack+Overflow/default.aspx">Stack Overflow</category><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/Benchmarking/default.aspx">Benchmarking</category></item><item><title>OMG Ponies!!! (Aka Humanity: Epic Fail)</title><link>http://msmvps.com/blogs/jon_skeet/archive/2009/11/02/omg-ponies-aka-humanity-epic-fail.aspx</link><pubDate>Mon, 02 Nov 2009 22:20:10 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1737163</guid><dc:creator>skeet</dc:creator><slash:comments>63</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/jon_skeet/rsscomments.aspx?PostID=1737163</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/jon_skeet/commentapi.aspx?PostID=1737163</wfw:comment><comments>http://msmvps.com/blogs/jon_skeet/archive/2009/11/02/omg-ponies-aka-humanity-epic-fail.aspx#comments</comments><description>&lt;p&gt;(Meta note: I tried to fix the layout for this, I really did. But my CSS skills are even worse than Tony&amp;#39;s. If anyone wants to send me a complete sample of how I should have laid this out, I&amp;#39;ll fix it up. Otherwise, this is as good as you&amp;#39;re going to get :)&lt;/p&gt;  &lt;p&gt;Last week at Stack Overflow DevDays, London I presented a talk on how humanity had made life difficult for software developers. There&amp;#39;s now a &lt;a href="http://vimeo.com/7516539"&gt;video&lt;/a&gt; of it on Vimeo - the audio is fairly poor at the very start, but it improves pretty soon. At the very end my video recorder ran out of battery, so you&amp;#39;ve just got my slides (and audio) for that portion. Anyway, here&amp;#39;s my slide deck and what I &lt;em&gt;meant&lt;/em&gt; to say. (A couple of times I forgot exactly which slide was coming next, unfortunately.)&lt;/p&gt;  &lt;p&gt;Click on any thumbnail for a larger view.&lt;/p&gt;  &lt;div style="display:inline-block;"&gt;&lt;a href="http://csharpindepth.com/Files/DevDays09/Image001.jpg"&gt;&lt;img src="http://csharpindepth.com/Files/DevDays09/thumbnails/Image001.jpg" alt="" /&gt;&lt;/a&gt;     &lt;p&gt;Good afternoon. This talk will be a little different from the others we&amp;#39;ve heard today... Joel mentioned on the podcast a long time ago that I&amp;#39;d talk about something &amp;quot;fun and esoteric&amp;quot; – and while I personally find C# 4 fun, I&amp;#39;m not sure that anyone could really call it esoteric. So instead, I thought I&amp;#39;d rant for half an hour about how mankind has made our life so difficult.&lt;/p&gt; &lt;/div&gt;  &lt;div style="display:inline-block;"&gt;&lt;a href="http://csharpindepth.com/Files/DevDays09/Image002.jpg"&gt;&lt;img src="http://csharpindepth.com/Files/DevDays09/thumbnails/Image002.jpg" alt="" /&gt;&lt;/a&gt;     &lt;p&gt;By way of introduction, I&amp;#39;m Jon Skeet. You may know me from questions such as &lt;a href="http://meta.stackoverflow.com/questions/9134/jon-skeet-facts"&gt;Jon Skeet Facts&lt;/a&gt;, &lt;a href="http://meta.stackoverflow.com/questions/555/why-does-jon-skeet-never-sleep"&gt;Why does Jon Skeet never sleep?&lt;/a&gt; and a few C# questions here and there. This is Tony the Pony. He&amp;#39;s a developer, but I&amp;#39;m afraid he&amp;#39;s not a very good one.&lt;/p&gt;    &lt;p&gt;(Tony whispers) Tony wants to make it clear that he&amp;#39;s not &lt;i&gt;just&lt;/i&gt; a developer. He has another job, as a magician. Are you any better at magic than development then? (Tony whispers) Oh, I see. He&amp;#39;s not very good at magic either – his repertoire is extremely limited. Basically he&amp;#39;s a one trick pony.&lt;/p&gt;    &lt;p&gt;Anyway, when it comes to software, Tony gets things done, but he&amp;#39;s not terribly smart. He comes unstuck with some of the most fundamental data types we have to work with. It&amp;#39;s really not his fault though – humanity has let him down by making things just way too complicated.&lt;/p&gt; &lt;/div&gt;  &lt;div style="display:inline-block;"&gt;&lt;a href="http://csharpindepth.com/Files/DevDays09/Image003.jpg"&gt;&lt;img src="http://csharpindepth.com/Files/DevDays09/thumbnails/Image003.jpg" alt="" /&gt;&lt;/a&gt;     &lt;p&gt;You see, the problem is that developers are already meant to be thinking about difficult things... coming up with a better widget to frobjugate the scarf handle, or whatever business problem they&amp;#39;re thinking about. They&amp;#39;ve really got enough to deal with – the simple things ought to be simple.&lt;/p&gt; &lt;/div&gt;  &lt;div style="display:inline-block;"&gt;&lt;a href="http://csharpindepth.com/Files/DevDays09/Image004.jpg"&gt;&lt;img src="http://csharpindepth.com/Files/DevDays09/thumbnails/Image004.jpg" alt="" /&gt;&lt;/a&gt;     &lt;p&gt;Unfortunately, time and time again we come up against problems with core elements of software engineering. Any resemblance between this slide and the coding horror logo is truly coincidental, by the way. Tasks which initially sound straightforward become insanely complicated. My aim in this talk is to distribute the blame amongst three groups of people.&lt;/p&gt; &lt;/div&gt;  &lt;div style="display:inline-block;"&gt;&lt;a href="http://csharpindepth.com/Files/DevDays09/Image005.jpg"&gt;&lt;img src="http://csharpindepth.com/Files/DevDays09/thumbnails/Image005.jpg" alt="" /&gt;&lt;/a&gt;     &lt;p&gt;First, let&amp;#39;s blame users – or mankind as a whole. Users always have an idea that what they want is easy, even if they can&amp;#39;t really articulate exactly what they &lt;i&gt;do&lt;/i&gt; want. Even if they &lt;i&gt;can&lt;/i&gt; give you requirements, chances are those will conflict – often in subtle ways – with requirements of others. A lot of the time, we wouldn&amp;#39;t even think of these problems as &amp;quot;requirements&amp;quot; – they&amp;#39;re just things that everyone expects to work in &amp;quot;the obvious way&amp;quot;. The trouble is that humanity has come up with all kinds of entirely different &amp;quot;obvious ways&amp;quot; of doing things. Mankind&amp;#39;s model of the universe is a surprisingly complicated one.&lt;/p&gt; &lt;/div&gt;  &lt;div style="display:inline-block;"&gt;&lt;a href="http://csharpindepth.com/Files/DevDays09/Image006.jpg"&gt;&lt;img src="http://csharpindepth.com/Files/DevDays09/thumbnails/Image006.jpg" alt="" /&gt;&lt;/a&gt;     &lt;p&gt;Next, I want to blame architects. I&amp;#39;m using the word &amp;quot;architect&amp;quot; in a very woolly sense here. I&amp;#39;m trying to describe the people who come up with operating systems, protocols, libraries, standards: things we build our software on top of. These are the people who have carefully considered the complicated model used by real people, stroked their beards, and designed something almost exactly as complicated, but not quite compatible with the original.&lt;/p&gt; &lt;/div&gt;  &lt;div style="display:inline-block;"&gt;&lt;a href="http://csharpindepth.com/Files/DevDays09/Image007.jpg"&gt;&lt;img src="http://csharpindepth.com/Files/DevDays09/thumbnails/Image007.jpg" alt="" /&gt;&lt;/a&gt;     &lt;p&gt;Finally, I&amp;#39;m going to blame us – common or garden developers. We have four problems: first, we don&amp;#39;t understand the complex model designed by mankind. Second, we don&amp;#39;t understand the complex model designed by the architects. Third, we don&amp;#39;t understand the applications we&amp;#39;re trying to build. Fourth, even when we get the first three bits right individually, we still screw up when we try to put them together.&lt;/p&gt;    &lt;p&gt;For the rest of this talk, I&amp;#39;m going to give three examples of how things go wrong. First, let&amp;#39;s talk about numbers.&lt;/p&gt; &lt;/div&gt;  &lt;div style="display:inline-block;"&gt;&lt;a href="http://csharpindepth.com/Files/DevDays09/Image008.jpg"&gt;&lt;img src="http://csharpindepth.com/Files/DevDays09/thumbnails/Image008.jpg" alt="" /&gt;&lt;/a&gt;     &lt;p&gt;You would think we would know how numbers work by now. We&amp;#39;ve all been doing maths since primary school. You&amp;#39;d also think that computers knew how to handle numbers by now – that&amp;#39;s basically what they&amp;#39;re built on. How is it that we can search billions of web pages in milliseconds, but we can&amp;#39;t get simple arithmetic right? How many times are we going to see Stack Overflow questions along the lines of &lt;a href="http://stackoverflow.com/questions/1420752"&gt;&amp;quot;Is double multiplication broken in .NET?&amp;quot;&lt;/a&gt;&lt;/p&gt;    &lt;p&gt;I blame evolution.&lt;/p&gt; &lt;/div&gt;  &lt;div style="display:inline-block;"&gt;&lt;a href="http://csharpindepth.com/Files/DevDays09/Image009.jpg"&gt;&lt;img src="http://csharpindepth.com/Files/DevDays09/thumbnails/Image009.jpg" alt="" /&gt;&lt;/a&gt;     &lt;p&gt;We have evolved with 8 fingers and 2 thumbs – a total of 10 digits. This was clearly a mistake. It has led to great suffering for developers. Life would have been a lot simpler if we&amp;#39;d only had eight digits.&lt;/p&gt; &lt;/div&gt;  &lt;div style="display:inline-block;"&gt;&lt;a href="http://csharpindepth.com/Files/DevDays09/Image010.jpg"&gt;&lt;img src="http://csharpindepth.com/Files/DevDays09/thumbnails/Image010.jpg" alt="" /&gt;&lt;/a&gt;     &lt;p&gt;Admittedly this gives us three bits, which isn&amp;#39;t quite ideal – but having 16 digits (fourteen fingers and two thumbs) or 4 digits (two fingers and two thumbs) could be tricky. At least with eight digits, we&amp;#39;d be able to fit in with binary &lt;i&gt;reasonably&lt;/i&gt; naturally. Now just so you don&amp;#39;t think I&amp;#39;m being completely impractical, there&amp;#39;s another solution – we could have just counted up to eight and ignored our thumbs. Indeed, we could even have used thumbs as parity bits. But no, mankind decided to count to ten, and that&amp;#39;s where all the problems started.&lt;/p&gt; &lt;/div&gt;  &lt;div style="display:inline-block;"&gt;&lt;a href="http://csharpindepth.com/Files/DevDays09/Image0011.jpg"&gt;&lt;img src="http://csharpindepth.com/Files/DevDays09/thumbnails/Image011.jpg" alt="" /&gt;&lt;/a&gt;     &lt;p&gt;Now, Tony – here&amp;#39;s a little puzzle for you. I want you to take a look at this piece of Java code (turn Tony to face screen). (Tony whispers) What do you mean you don&amp;#39;t know Java? All right, here&amp;#39;s the C# code instead...&lt;/p&gt; &lt;/div&gt;  &lt;div style="display:inline-block;"&gt;&lt;a href="http://csharpindepth.com/Files/DevDays09/Image011a.jpg"&gt;&lt;img src="http://csharpindepth.com/Files/DevDays09/thumbnails/Image011a.jpg" alt="" /&gt;&lt;/a&gt;     &lt;p&gt;Is that better? (Tony nods enthusiastically) So, Tony, I want you to tell me the value of d after this line has executed. (Tony whispers)&lt;/p&gt; &lt;/div&gt;  &lt;div style="display:inline-block;"&gt;&lt;a href="http://csharpindepth.com/Files/DevDays09/Image011b.jpg"&gt;&lt;img src="http://csharpindepth.com/Files/DevDays09/thumbnails/Image011b.jpg" alt="" /&gt;&lt;/a&gt;     &lt;p&gt;Tony thinks it&amp;#39;s 0.3 Poor Tony. Why on earth would you think that? Oh dear. Sorry, no it&amp;#39;s not.&lt;/p&gt; &lt;/div&gt;  &lt;div style="display:inline-block;"&gt;&lt;a href="http://csharpindepth.com/Files/DevDays09/Image011c.jpg"&gt;&lt;img src="http://csharpindepth.com/Files/DevDays09/thumbnails/Image011c.jpg" alt="" /&gt;&lt;/a&gt;     &lt;p&gt;No, you were certainly close, but the exact value is:&lt;/p&gt; &lt;/div&gt;  &lt;div style="display:inline-block;"&gt;&lt;a href="http://csharpindepth.com/Files/DevDays09/Image012.jpg"&gt;&lt;img src="http://csharpindepth.com/Files/DevDays09/thumbnails/Image012.jpg" alt="" /&gt;&lt;/a&gt;     &lt;p&gt;0.299999 - Well, I&amp;#39;m not going to read it all out, but that&amp;#39;s the exact value. And it &lt;i&gt;is&lt;/i&gt; an exact value – the compiler has approximated the 0.3 in the source code to the nearest number which can be exactly represented by a double. It&amp;#39;s not the computer&amp;#39;s fault that we have this bizarre expectation that a number in our source code will be accurately represented internally.&lt;/p&gt; &lt;/div&gt;  &lt;div style="display:inline-block;"&gt;&lt;a href="http://csharpindepth.com/Files/DevDays09/Image013.jpg"&gt;&lt;img src="http://csharpindepth.com/Files/DevDays09/thumbnails/Image013.jpg" alt="" /&gt;&lt;/a&gt;     &lt;p&gt;Let&amp;#39;s take a look at two more numbers... 5 and a half in both cases. Now it doesn&amp;#39;t &lt;i&gt;look&lt;/i&gt; like these are really different – but they are. Indeed, if I were representing these two numbers in a program, I&amp;#39;d quite possibly use different types for them. The first value is discrete – there&amp;#39;s a single jump from £5.50 to £5.51, and those are exact amounts of money... whereas when we measure the mass of something, we always really mean “to two decimal places” or something similar. Nothing weighs &lt;i&gt;exactly&lt;/i&gt; five and a half kilograms. They&amp;#39;re fundamentally different concepts, they just happen to have the same value. What do you do with them? Well, continuous numbers are often best represented as float/double, whereas discrete decimal numbers are usually best represented using a decimal-based type.&lt;/p&gt;    &lt;p&gt;Now I&amp;#39;ve ignored an awful lot of things about numbers which can also trip us up – signed and unsigned, overflow, not-a-number values, infinities, normalised and denormal numbers, parsing and formatting, all kinds of stuff. But we should move on. Next stop, text.&lt;/p&gt; &lt;/div&gt;  &lt;div style="display:inline-block;"&gt;&lt;a href="http://csharpindepth.com/Files/DevDays09/Image14b.jpg"&gt;&lt;img src="http://csharpindepth.com/Files/DevDays09/thumbnails/Image14b.jpg" alt="" /&gt;&lt;/a&gt;     &lt;p&gt;Okay, so numbers aren&amp;#39;t as simple as we&amp;#39;d like them to be. Text ought to be easy though, right? I mean, my five year old son can read and write – how hard can it be? One bit of trivia - when I originally copied this out by hand, I missed out &amp;quot;ipsum.&amp;quot; Note to self: if you&amp;#39;re going to copy out &amp;quot;lorem ipsum&amp;quot; the two words you really, &lt;i&gt;really&lt;/i&gt; need to get at least &lt;i&gt;those&lt;/i&gt; words right. Fail.&lt;/p&gt; &lt;/div&gt;  &lt;div style="display:inline-block;"&gt;&lt;a href="http://csharpindepth.com/Files/DevDays09/Image015.jpg"&gt;&lt;img src="http://csharpindepth.com/Files/DevDays09/thumbnails/Image015.jpg" alt="" /&gt;&lt;/a&gt;     &lt;p&gt;Of course, I&amp;#39;m sure pretty much everyone here knows that text is actually a pain in the neck. Again, I will blame humanity. Here we have two sets of people using completely different characters, speaking different languages, and quite possibly reading in different directions. Apologies if the characters on the right accidentally spell a rude word, by the way - I just picked a few random Kanji characters from the Unicode charts. &lt;em&gt;(As pointed out in the comments, these aren&amp;#39;t actually Kanji characters anyway. They&amp;#39;re Katakana characters. Doh!)&lt;/em&gt; Cultural diversity has screwed over computing, basically.&lt;/p&gt;    &lt;p&gt;However, let&amp;#39;s take the fact that we&amp;#39;ve got lots of characters as a given. Unicode sorts all that out, right? Let&amp;#39;s see. Time for a coding exercise – Tony, I&amp;#39;d like you to write some code to reverse a string. (Tony whispers) No, I&amp;#39;m not going to start up Visual Studio for you. (Tony whispers) You&amp;#39;ve magically written it on the next slide? Okay, let&amp;#39;s take a look.&lt;/p&gt; &lt;/div&gt;  &lt;div style="display:inline-block;"&gt;&lt;a href="http://csharpindepth.com/Files/DevDays09/Image016.jpg"&gt;&lt;img src="http://csharpindepth.com/Files/DevDays09/thumbnails/Image016.jpg" alt="" /&gt;&lt;/a&gt;     &lt;p&gt;Well, this looks quite promising. We&amp;#39;re taking a string, converting it into a character array, reversing that array, and then building a new string. I&amp;#39;m impressed, Tony – you&amp;#39;ve avoided pointless string concatenation and everything. (Tony is happy.) Unfortunately...&lt;/p&gt; &lt;/div&gt;  &lt;div style="display:inline-block;"&gt;&lt;a href="http://csharpindepth.com/Files/DevDays09/Image016a.jpg"&gt;&lt;img src="http://csharpindepth.com/Files/DevDays09/thumbnails/Image016a.jpg" alt="" /&gt;&lt;/a&gt;     &lt;p&gt;... it&amp;#39;s broken. I&amp;#39;m just going to give &lt;i&gt;one&lt;/i&gt; example of how it&amp;#39;s broken – there are lots of others along the same lines. Let&amp;#39;s reverse one of my favourite musicals...&lt;/p&gt; &lt;/div&gt;  &lt;div style="display:inline-block;"&gt;&lt;a href="http://csharpindepth.com/Files/DevDays09/Image017a.jpg"&gt;&lt;img src="http://csharpindepth.com/Files/DevDays09/thumbnails/Image017a.jpg" alt="" /&gt;&lt;/a&gt;     &lt;p&gt;Here&amp;#39;s one way of representing Les Miserables as a Unicode string. Instead of using one code point for the “e acute”, I&amp;#39;ve used a combining character to represent the accent, and then an unaccented ASCII e. Display this in a GUI, and it looks fine... but when we apply Tony&amp;#39;s reversing code...&lt;/p&gt; &lt;/div&gt;  &lt;div style="display:inline-block;"&gt;&lt;a href="http://csharpindepth.com/Files/DevDays09/Image017b.jpg"&gt;&lt;img src="http://csharpindepth.com/Files/DevDays09/thumbnails/Image017b.jpg" alt="" /&gt;&lt;/a&gt;     &lt;p&gt;... the combining character ends up &lt;i&gt;after&lt;/i&gt; the e, so we get an “s acute” instead. Sorry Tony. The Unicode designers with their fancy schemes have failed you.&lt;/p&gt;    &lt;blockquote&gt;     &lt;p&gt;EDIT: In fact, not only have the Unicode designers made things difficult, but so have implementers. You see, I couldn&amp;#39;t remember whether combining characters came before or after base characters, so I wrote a little Windows Forms app to check. That app displayed &amp;quot;Les Mis\u0301erables&amp;quot; as &amp;quot;Les Misérables&amp;quot;. Then, based on the comments below, I checked with the standard – and the &lt;a href="http://unicode.org/faq/char_combmark.html"&gt;Unicode combining marks FAQ&lt;/a&gt; indicates pretty clearly that the base character comes &lt;em&gt;before&lt;/em&gt; the combining character. Further failure points to both me and someone in Microsoft, unless I&amp;#39;m missing something. Thanks to McDowell for pointing this out in the comments. If I ever give this presentation again, I&amp;#39;ll be sure to point it out. WPF gets it right, by the way. Update: this can be fixed in Windows Forms by setting the &lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.forms.label.usecompatibletextrendering.aspx"&gt;UseCompatibleTextRendering&lt;/a&gt; property to false (or setting the default to false). Apparently the default is set to false when you create a new WinForms project in VS2008. Shame I tend to write &amp;quot;quick check&amp;quot; programs in a plain text editor…&lt;/p&gt;      &lt;p&gt;Of course the basic point about reversal still holds, but with the correct starting string you&amp;#39;d end up with an acute over the r, not the s.&lt;/p&gt;   &lt;/blockquote&gt;    &lt;p&gt;It&amp;#39;s not like the problems are solely in the realm of non-ASCII characters though. I present to you...&lt;/p&gt; &lt;/div&gt;  &lt;div style="display:inline-block;"&gt;&lt;a href="http://csharpindepth.com/Files/DevDays09/Image018.jpg"&gt;&lt;img src="http://csharpindepth.com/Files/DevDays09/thumbnails/Image018.jpg" alt="" /&gt;&lt;/a&gt;     &lt;p&gt;A line break. Or rather, &lt;i&gt;one&lt;/i&gt; of the representations of a line break. As if the natural cultural diversity of humanity hasn&amp;#39;t caused enough problems, software decided to get involved and have line break diversity. Heck, we&amp;#39;re not even just limited to CR, LF and CRLF – Unicode has its own special line terminator character as well, just for kicks.&lt;/p&gt; &lt;/div&gt;  &lt;div style="display:inline-block;"&gt;&lt;a href="http://csharpindepth.com/Files/DevDays09/Image019.jpg"&gt;&lt;img src="http://csharpindepth.com/Files/DevDays09/thumbnails/Image019.jpg" alt="" /&gt;&lt;/a&gt;     &lt;p&gt;To prove this isn&amp;#39;t just a problem for toy examples, here&amp;#39;s something that really bit me, back about 9 or 10 years ago. Here&amp;#39;s some code which tries to do a case-insensitive comparison for the text &amp;quot;MAIL&amp;quot; in Java. Can anyone spot the problem?&lt;/p&gt;    &lt;p&gt;It fails in Turkey. This is reasonably well known now – there&amp;#39;s a page about the “Turkey test” encouraging you to try your applications in a Turkish locale – but at the time it was a mystery to me. If you&amp;#39;re not familiar with this, the problem is that if you upper-case an “i” in Turkish, you end up with an “I” with a dot on it. This code went into production, and we had a customer in Turkey whose server was behaving oddly. As you can imagine, if you&amp;#39;re not aware of that potential problem, it can take a heck of a long time to find that kind of bug.&lt;/p&gt; &lt;/div&gt;  &lt;div style="display:inline-block;"&gt;&lt;a href="http://csharpindepth.com/Files/DevDays09/Image020a.jpg"&gt;&lt;img src="http://csharpindepth.com/Files/DevDays09/thumbnails/Image020a.jpg" alt="" /&gt;&lt;/a&gt;     &lt;p&gt;Here&amp;#39;s some code from a newsgroup post. It&amp;#39;s somewhat inefficient code to collapse multiple spaces down to a single one. Leaving aside the inefficiency, it looks like it should work. This was before we had String.Contains, so it&amp;#39;s using IndexOf to check whether we&amp;#39;ve got a double space. While we can find two spaces in a row, we&amp;#39;ll replace any occurrence of two spaces with a single space. We&amp;#39;re assigning the result of string.Replace back to the same variable, so that&amp;#39;s avoided one common problem... so how could this fail?&lt;/p&gt; &lt;/div&gt;  &lt;div style="display:inline-block;"&gt;&lt;a href="http://csharpindepth.com/Files/DevDays09/Image020b.jpg"&gt;&lt;img src="http://csharpindepth.com/Files/DevDays09/thumbnails/Image020b.jpg" alt="" /&gt;&lt;/a&gt;     &lt;p&gt;This string will cause that code to go into a tight loop, due to this evil character here. It&amp;#39;s a &amp;quot;zero-width non-joiner&amp;quot; – basically a hint that the two characters either side of it shouldn&amp;#39;t be squashed up too closely together. &lt;code&gt;IndexOf&lt;/code&gt; ignores it, but &lt;code&gt;Replace&lt;/code&gt; doesn&amp;#39;t. Ouch.&lt;/p&gt;    &lt;p&gt;Now I&amp;#39;m not showing these examples to claim I&amp;#39;m some sort of Unicode expert – I&amp;#39;m really, really not. These are just corner cases I &lt;i&gt;happen&lt;/i&gt; to have run into. Just like with numbers, I&amp;#39;ve left out a whole bunch of problems like bidi, encodings, translation, culture-sensitive parsing and the like.&lt;/p&gt;    &lt;p&gt;Given the vast array of writing systems the world has come up with – and variations within those systems – any attempt to model text is going to be complicated. The problems come from the inherent complexity, some additional complexity introduced by things like surrogate pairs, and developers simply not having the time to become experts on text processing. &lt;/p&gt;    &lt;p&gt;So, we fail at both numbers and text. How about time?&lt;/p&gt; &lt;/div&gt;  &lt;div style="display:inline-block;"&gt;&lt;a href="http://csharpindepth.com/Files/DevDays09/Image021.jpg"&gt;&lt;img src="http://csharpindepth.com/Files/DevDays09/thumbnails/Image021.jpg" alt="" /&gt;&lt;/a&gt;     &lt;p&gt;I&amp;#39;m biased when it comes to time-related problems. For the last year or so I&amp;#39;ve been working on the Google&amp;#39;s implementation of ActiveSync, mostly focusing on the calendar side of things. That means I&amp;#39;ve been exposed to more time-based code than most developers... but it&amp;#39;s still a reasonably common area, as you can tell from the number of related questions on Stack Overflow.&lt;/p&gt; &lt;/div&gt;  &lt;div style="display:inline-block;"&gt;&lt;a href="http://csharpindepth.com/Files/DevDays09/Image022.jpg"&gt;&lt;img src="http://csharpindepth.com/Files/DevDays09/thumbnails/Image022.jpg" alt="" /&gt;&lt;/a&gt;     &lt;p&gt;To make things slightly simpler, let&amp;#39;s ignore relativity. Let&amp;#39;s pretend that time is linear – after all, most systems are meant to be modelling the human concept of time, which definitely &lt;i&gt;doesn&amp;#39;t&lt;/i&gt; include relativity.&lt;/p&gt; &lt;/div&gt;  &lt;div style="display:inline-block;"&gt;&lt;a href="http://csharpindepth.com/Files/DevDays09/Image023.jpg"&gt;&lt;img src="http://csharpindepth.com/Files/DevDays09/thumbnails/Image023.jpg" alt="" /&gt;&lt;/a&gt;     &lt;p&gt;Likewise, let&amp;#39;s ignore leap seconds. This isn&amp;#39;t &lt;i&gt;always&lt;/i&gt; a good idea, and there are some wrinkles around library support. For example, Java &lt;i&gt;explicitly&lt;/i&gt; says that java.util.Date and Calendar may or may not account for leap seconds depending on the host support. So, it&amp;#39;s good to know how predictable &lt;i&gt;that&lt;/i&gt; makes our software... I&amp;#39;ve tried reading various explanations of leap seconds, and always ended up with a headache. For the purposes of this talk, I&amp;#39;m going to assert that they don&amp;#39;t exist.&lt;/p&gt; &lt;/div&gt;  &lt;div style="display:inline-block;"&gt;&lt;a href="http://csharpindepth.com/Files/DevDays09/Image024.jpg"&gt;&lt;img src="http://csharpindepth.com/Files/DevDays09/thumbnails/Image024.jpg" alt="" /&gt;&lt;/a&gt;     &lt;p&gt;Okay, so let&amp;#39;s start with something simple. Tony, what&amp;#39;s the time on this slide? (Tony whispers) Tony doesn&amp;#39;t want to answer. Anyone? &lt;i&gt;(Audience responds.)&lt;/i&gt; Yes, about 5 past 3 on October 28&lt;sup&gt;th&lt;/sup&gt;. So what&amp;#39;s the difference between now and the time on this slide? (Audience response.) No, it&amp;#39;s actually nearly twelve hours... this clock is showing 5 past 3 in the morning. Tony&amp;#39;s answer was actually the right one, in many ways... this slide has a hopeless amount of ambiguity. It&amp;#39;s not as bad as it might be, admittedly. Imagine if it said October 11&lt;sup&gt;th&lt;/sup&gt;... Jeff and Joel would be nearly a month out of sync with the rest of us. And then even if we get the date and the time right, it&amp;#39;s still ambiguous... because of time zones.&lt;/p&gt; &lt;/div&gt;  &lt;div style="display:inline-block;"&gt;&lt;a href="http://csharpindepth.com/Files/DevDays09/Image025.jpg"&gt;&lt;img src="http://csharpindepth.com/Files/DevDays09/thumbnails/Image025.jpg" alt="" /&gt;&lt;/a&gt;     &lt;p&gt;Ah, time zones. My favourite source of WTFs. I could rant for hours about them – but I&amp;#39;ll try not to. I&amp;#39;d just like to point out a few of the idiosyncrasies I&amp;#39;ve encountered. Let&amp;#39;s start off with the time zones on this slide. Notice anything strange? (Audience or whisper from Tony) Yes, CST is there three times. Once for Central Standard Time in the US – which is UTC-6. It&amp;#39;s also Central Standard Time in Australia – where it&amp;#39;s UTC+9.30. It&amp;#39;s also Central &lt;i&gt;Summer&lt;/i&gt; Time in Australia, where it&amp;#39;s UTC+10.30. I think it takes a special kind of incompetence to use the same acronym in the same place for different offsets.&lt;/p&gt;    &lt;p&gt;Then let&amp;#39;s consider time zones changing. One of the problems I face is having to encode or decode a time zone representation from a single pattern – something like &amp;quot;It&amp;#39;s UTC-3 or -2, and daylight savings are applied from the third Sunday in March to the first Sunday in November&amp;quot;. That&amp;#39;s all very well until the system changes. Some countries give plenty of warning of this... but on October 7&lt;sup&gt;th&lt;/sup&gt; this year, Argentina announced that it wasn&amp;#39;t going to use daylight saving time any more... 11 days before its next transition. The reason? Their dams are 90% full. I only heard about this due to one of my unit tests failing. For various complicated reasons, a unit test which expected to recognise the time zone for Godthab actually thought it was Buenos Aires. So due to rainfall thousands of miles away, my unit test had moved Greenland into Argentina. Fail.&lt;/p&gt;    &lt;p&gt;If you want more time zone incidents, talk to me afterwards. It&amp;#39;s a whole world of pain. I suggest we move away from time zones entirely. In fact, I suggest we adopt a much simpler system of time. I&amp;#39;m proud to present my proposal for &lt;i&gt;coffee time&lt;/i&gt;. This is a system which determines the current time based on the answer to the question: &amp;quot;Is it time for coffee?&amp;quot; This is what the clock looks like:&lt;/p&gt; &lt;/div&gt;  &lt;div style="display:inline-block;"&gt;&lt;a href="http://csharpindepth.com/Files/DevDays09/Image026.jpg"&gt;&lt;img src="http://csharpindepth.com/Files/DevDays09/thumbnails/Image026.jpg" alt="" /&gt;&lt;/a&gt;     &lt;p&gt;This clock is correct all over the world, is very cheap to produce, and is guaranteed to be accurate forever. Batteries not required.&lt;/p&gt;    &lt;p&gt;So where are we?&lt;/p&gt; &lt;/div&gt;  &lt;div style="display:inline-block;"&gt;&lt;a href="http://csharpindepth.com/Files/DevDays09/Image027a.jpg"&gt;&lt;img src="http://csharpindepth.com/Files/DevDays09/thumbnails/Image027a.jpg" alt="" /&gt;&lt;/a&gt;     &lt;p&gt;The real world has failed us. It has concentrated on local simplicity, leading to global complexity. It&amp;#39;s easy to organise a meeting if everyone is in the same time zone – but once you get different continents involved, invariably people get confused. It&amp;#39;s easy to get writing to work uniformly left to right or uniformly right to left – but if you&amp;#39;ve got a mixture, it becomes really hard to keep track of. The diversity which makes humanity such an interesting species is the curse of computing.&lt;/p&gt; &lt;/div&gt;  &lt;div style="display:inline-block;"&gt;&lt;a href="http://csharpindepth.com/Files/DevDays09/Image027b.jpg"&gt;&lt;img src="http://csharpindepth.com/Files/DevDays09/thumbnails/Image027b.jpg" alt="" /&gt;&lt;/a&gt;     &lt;p&gt;When computer systems have tried to model this complexity, they&amp;#39;ve failed horribly. Exhibit A: &lt;code&gt;java.util.Calendar&lt;/code&gt;, with its incomprehensible set of precedence rules. Exhibit B: .NET&amp;#39;s date and time API, which until relatively recently didn&amp;#39;t let you represent any time zone other than UTC or the one local to the system.&lt;/p&gt; &lt;/div&gt;  &lt;div style="display:inline-block;"&gt;&lt;a href="http://csharpindepth.com/Files/DevDays09/Image027c.jpg"&gt;&lt;img src="http://csharpindepth.com/Files/DevDays09/thumbnails/Image027c.jpg" alt="" /&gt;&lt;/a&gt;     &lt;p&gt;Developers have, collectively, failed to understand both the models and the real world. We only need one exhibit this time: the questions on Stack Overflow. Developers asking questions around double, or Unicode, or dates and times aren&amp;#39;t stupid. They&amp;#39;ve just been concentrating on other topics. They&amp;#39;ve made an assumption that the core building blocks of their trade would be simple, and it turns out they&amp;#39;re not.&lt;/p&gt; &lt;/div&gt;  &lt;div style="display:inline-block;"&gt;&lt;a href="http://csharpindepth.com/Files/DevDays09/Image028.jpg"&gt;&lt;img src="http://csharpindepth.com/Files/DevDays09/thumbnails/Image028.jpg" alt="" /&gt;&lt;/a&gt;     &lt;p&gt;This has all been pretty negative, for which I apologise. I&amp;#39;m not going to claim to have a complete solution to all of this – but I do want to give a small ray of hope. All this complexity can be managed to some extent, if you do three things.&lt;/p&gt;    &lt;p&gt;First, try not to take on more complexity than you need. If you can absolutely guarantee that you won&amp;#39;t need to translate your app, it&amp;#39;ll make your life a lot easier. If you don&amp;#39;t need to deal with different time zones, you can rejoice. Of course, if you write a lot of code under a set of assumptions which then changes, you&amp;#39;re in trouble... but quite often you &lt;i&gt;can&lt;/i&gt; take the &amp;quot;You ain&amp;#39;t gonna need it&amp;quot; approach.&lt;/p&gt;    &lt;p&gt;Next, learn just enough about the problem space so that you know more than your application&amp;#39;s requirements. You don&amp;#39;t need to know everything about Unicode – but you need to be aware of which corner cases might affect your application. You don&amp;#39;t need to know everything about how denormal number representation, but you may well need to know how rounding should be applied in your reports. If your knowledge is just a bit bigger than the code you need to write, you should be able to be reasonably comfortable.&lt;/p&gt;    &lt;p&gt;Pick the right platforms and libraries. Yes, there are some crummy frameworks around. There are also some good ones. What&amp;#39;s the canonical answer to almost any question about &lt;code&gt;java.util.Calendar&lt;/code&gt;? Use &lt;a href="http://joda-time.sf.net/"&gt;Joda Time&lt;/a&gt; instead. There are similar libraries like ICU – written by genuine experts in these thorny areas. The difference a good library can make is absolutely enormous.&lt;/p&gt;    &lt;p&gt;None of this will make you a good developer. Tony&amp;#39;s still likely to mis-spell his &amp;quot;main&amp;quot; method through force of habit. You&amp;#39;re still going to get off by one errors. You&amp;#39;re still going to forget to close database connections. But if you can at least get a handle on &lt;i&gt;some&lt;/i&gt; of the complexity of software engineering, it&amp;#39;s a start.&lt;/p&gt;    &lt;p&gt;Thanks for listening.&lt;/p&gt; &lt;/div&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1737163" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/Speaking+engagements/default.aspx">Speaking engagements</category><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/Stack+Overflow/default.aspx">Stack Overflow</category></item><item><title>Iterating atomically</title><link>http://msmvps.com/blogs/jon_skeet/archive/2009/10/23/iterating-atomically.aspx</link><pubDate>Fri, 23 Oct 2009 21:20:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1734632</guid><dc:creator>skeet</dc:creator><slash:comments>34</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/jon_skeet/rsscomments.aspx?PostID=1734632</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/jon_skeet/commentapi.aspx?PostID=1734632</wfw:comment><comments>http://msmvps.com/blogs/jon_skeet/archive/2009/10/23/iterating-atomically.aspx#comments</comments><description>&lt;p&gt;The IEnumerable&amp;lt;T&amp;gt; and IEnumerator&amp;lt;T&amp;gt; interfaces in .NET are interesting. They crop up an awful lot, but hardly anyone ever calls them directly - you almost always use a foreach loop to iterate over the collection. That hides all the calls to GetEnumerator(), MoveNext() and Current. Likewise iterator blocks hide the details when you want to implement the interfaces. However, sometimes details matter - such as for &lt;a href="http://stackoverflow.com/questions/1605745"&gt;this recent Stack Overflow question&lt;/a&gt;. The question asks how to create a thread-safe iterator - one that can be called from multiple threads. This is not about iterating over a collection &lt;em&gt;n&lt;/em&gt; times independently on &lt;em&gt;n&lt;/em&gt; different threads - this is about iterating over a collection &lt;em&gt;once&lt;/em&gt; without skipping or duplicating. Imagine it&amp;#39;s some set of jobs that we have to complete. We assume that the iterator itself is thread-safe to the extent that calls from different threads &lt;em&gt;at different times, with intervening locks&lt;/em&gt; will be handled reasonably. This is reasonable - basically, so long as it isn&amp;#39;t going out of its way to be thread-hostile, we should be okay. We also assume that no-one is trying to write to the collection at the same time.&lt;/p&gt;
&lt;p&gt;Sounds easy, right? Well, no... because the IEnumerator&amp;lt;T&amp;gt; interface has two members which we effectively want to call atomically. In particular, we &lt;em&gt;don&amp;#39;t&lt;/em&gt; want the collection { &amp;quot;a&amp;quot;, &amp;quot;b&amp;quot; } to be iterated like this:&lt;/p&gt;
&lt;table width="400" cellpadding="2" cellspacing="0" border="0"&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td width="200" valign="top"&gt;Thread 1&lt;/td&gt;
&lt;td width="200" valign="top"&gt;Thread 2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td width="200" valign="top"&gt;MoveNext()&lt;/td&gt;
&lt;td width="200" valign="top"&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td width="200" valign="top"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td width="200" valign="top"&gt;MoveNext()&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td width="200" valign="top"&gt;Current&lt;/td&gt;
&lt;td width="200" valign="top"&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td width="200" valign="top"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td width="200" valign="top"&gt;Current&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;That way we&amp;#39;ll end up not processing the first item at all, and the second item twice.&lt;/p&gt;
&lt;p&gt;There are two ways of approaching this problem. In both cases I&amp;#39;ve started with IEnumerable&amp;lt;T&amp;gt; for consistency, but in fact it&amp;#39;s IEnumerator&amp;lt;T&amp;gt; which is the interesting bit. In particular, we&amp;#39;re not going to be able to iterate over our result anyway, as each thread needs to have the same IEnumerator&amp;lt;T&amp;gt; - which it won&amp;#39;t do if each of them uses foreach (which calls GetEnumerator() to start with).&lt;/p&gt;
&lt;h3&gt;Fix the interface&lt;/h3&gt;
&lt;p&gt;First we&amp;#39;ll try to fix the interface to look how it should have looked to start with, at least from the point of view of atomicity. Here are the new interfaces:&lt;/p&gt;
&lt;div class="code"&gt;&lt;span class="Modifier"&gt;public&lt;/span&gt;&amp;nbsp;&lt;span class="ReferenceType"&gt;interface&lt;/span&gt; IAtomicEnumerable&amp;lt;T&amp;gt;     &lt;br /&gt;{     &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; IAtomicEnumerator&amp;lt;T&amp;gt; GetEnumerator();     &lt;br /&gt;}     &lt;br /&gt;    &lt;br /&gt;&lt;span class="Modifier"&gt;public&lt;/span&gt;&amp;nbsp;&lt;span class="ReferenceType"&gt;interface&lt;/span&gt; IAtomicEnumerator&amp;lt;T&amp;gt;     &lt;br /&gt;{     &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="ValueType"&gt;bool&lt;/span&gt; TryMoveNext(&lt;span class="MethodParameter"&gt;out&lt;/span&gt; T nextValue);     &lt;br /&gt;} &lt;/div&gt;
&lt;p&gt;One thing you may notice is that we&amp;#39;re not implementing IDisposable. That&amp;#39;s basically because it&amp;#39;s a pain to do so when you think about a multi-threaded environment. Indeed, it&amp;#39;s possibly one of the biggest arguments against something of this nature. At what point do you dispose? Just because &lt;em&gt;one&lt;/em&gt; thread finished doesn&amp;#39;t mean that the rest of them have... don&amp;#39;t forget that &amp;quot;finish&amp;quot; might mean &amp;quot;an exception was thrown while processing the job, I&amp;#39;m bailing out&amp;quot;. You&amp;#39;d need some sort of co-ordinator to make sure that &lt;em&gt;everyone&lt;/em&gt; is finished before you actually do any clean-up. Anyway, the nice thing about this being a blog post is we can ignore that little thorny issue :)&lt;/p&gt;
&lt;p&gt;The important point is that we now have a single method in IAtomicEnumerator&amp;lt;T&amp;gt; - TryMoveNext, which works the way you&amp;#39;d expect it to. It atomically attempts to move to the next item, returns whether or not it succeeded, and sets an out parameter with the next value if it &lt;em&gt;did&lt;/em&gt; succeed. Now there&amp;#39;s no chance of two threads using the method and stomping on each other&amp;#39;s values (unless they&amp;#39;re silly and use the same variable for the out parameter).&lt;/p&gt;
&lt;p&gt;It&amp;#39;s reasonably easy to wrap the standard interfaces in order to implement this interface:&lt;/p&gt;
&lt;div class="code"&gt;&lt;span class="XmlComment"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;     &lt;br /&gt;&lt;span class="XmlComment"&gt;/// Wraps a normal IEnumerable[T] up to implement IAtomicEnumerable[T].&lt;/span&gt;     &lt;br /&gt;&lt;span class="XmlComment"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;     &lt;br /&gt;&lt;span class="Modifier"&gt;public&lt;/span&gt;&amp;nbsp;&lt;span class="Modifier"&gt;sealed&lt;/span&gt;&amp;nbsp;&lt;span class="ReferenceType"&gt;class&lt;/span&gt; AtomicEnumerable&amp;lt;T&amp;gt; : IAtomicEnumerable&amp;lt;T&amp;gt;     &lt;br /&gt;{     &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="Modifier"&gt;private&lt;/span&gt;&amp;nbsp;&lt;span class="Modifier"&gt;readonly&lt;/span&gt; IEnumerable&amp;lt;T&amp;gt; original;     &lt;br /&gt;    &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="Modifier"&gt;public&lt;/span&gt; AtomicEnumerable(IEnumerable&amp;lt;T&amp;gt; original)     &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {     &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="Keyword"&gt;this&lt;/span&gt;.original = original;     &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }     &lt;br /&gt;    &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="Modifier"&gt;public&lt;/span&gt; IAtomicEnumerator&amp;lt;T&amp;gt; GetEnumerator()     &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {     &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="Statement"&gt;return&lt;/span&gt;&amp;nbsp;&lt;span class="Keyword"&gt;new&lt;/span&gt; AtomicEnumerator(original.GetEnumerator());     &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }     &lt;br /&gt;    &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="XmlComment"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;     &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="XmlComment"&gt;/// Implementation of IAtomicEnumerator[T] to wrap IEnumerator[T].&lt;/span&gt;     &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="XmlComment"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;     &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="Modifier"&gt;private&lt;/span&gt;&amp;nbsp;&lt;span class="Modifier"&gt;sealed&lt;/span&gt;&amp;nbsp;&lt;span class="ReferenceType"&gt;class&lt;/span&gt; AtomicEnumerator : IAtomicEnumerator&amp;lt;T&amp;gt;     &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {     &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="Modifier"&gt;private&lt;/span&gt;&amp;nbsp;&lt;span class="Modifier"&gt;readonly&lt;/span&gt; IEnumerator&amp;lt;T&amp;gt; original;     &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="Modifier"&gt;private&lt;/span&gt;&amp;nbsp;&lt;span class="Modifier"&gt;readonly&lt;/span&gt;&amp;nbsp;&lt;span class="ReferenceType"&gt;object&lt;/span&gt; padlock = &lt;span class="Keyword"&gt;new&lt;/span&gt;&amp;nbsp;&lt;span class="ReferenceType"&gt;object&lt;/span&gt;();     &lt;br /&gt;    &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="Modifier"&gt;internal&lt;/span&gt; AtomicEnumerator(IEnumerator&amp;lt;T&amp;gt; original)     &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {     &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="Keyword"&gt;this&lt;/span&gt;.original = original;     &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }     &lt;br /&gt;    &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="Modifier"&gt;public&lt;/span&gt;&amp;nbsp;&lt;span class="ValueType"&gt;bool&lt;/span&gt; TryMoveNext(&lt;span class="MethodParameter"&gt;out&lt;/span&gt; T value)     &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {     &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="Statement"&gt;lock&lt;/span&gt; (padlock)     &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {     &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="ValueType"&gt;bool&lt;/span&gt; hadNext = original.MoveNext();     &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; value = hadNext ? original.Current : &lt;span class="Modifier"&gt;default&lt;/span&gt;(T);     &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="Statement"&gt;return&lt;/span&gt; hadNext;     &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }     &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }     &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }     &lt;br /&gt;} &lt;/div&gt;
&lt;p&gt;Just ignore the fact that I never dispose of the original IEnumerator&amp;lt;T&amp;gt; :)&lt;/p&gt;
&lt;p&gt;We use a simple lock to make sure that MoveNext() and Current always happen together - that nothing else is going to call MoveNext() between our TryMoveNext() calling it, and it fetching the current value.&lt;/p&gt;
&lt;p&gt;Obviously you&amp;#39;d need to write your own code to actually &lt;em&gt;use&lt;/em&gt; this sort of iterator, but it would be quite simple:&lt;/p&gt;
&lt;div class="code"&gt;T value;    &lt;br /&gt;&lt;span class="Statement"&gt;while&lt;/span&gt; (iterator.TryMoveNext(&lt;span class="MethodParameter"&gt;out&lt;/span&gt; value))     &lt;br /&gt;{     &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="InlineComment"&gt;// Use value&lt;/span&gt;     &lt;br /&gt;} &lt;/div&gt;
&lt;p&gt;However, you may already have code which wants to use an IEnumerator&amp;lt;T&amp;gt;. Let&amp;#39;s see what else we can do.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Using thread local variables to fake it&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;.NET 4.0 has a very useful type called ThreadLocal&amp;lt;T&amp;gt;. It does basically what you&amp;#39;d expect it to, with nice features such as being able to supply a delegate to be executed on each thread to provide the initial value. We can use a thread local to make sure that so long as we call both MoveNext() and Current atomically when we&amp;#39;re asked to move to the next element, we can get back the right value for Current later on. It has to be thread local because we&amp;#39;re sharing a single IEnumerator&amp;lt;T&amp;gt; across multiple threads - each needs its own separate storage.&lt;/p&gt;
&lt;p&gt;This is also the approach we&amp;#39;d use if we wanted to wrap an IAtomicEnumerator&amp;lt;T&amp;gt; in an IEnumerator&amp;lt;T&amp;gt;, by the way. Here&amp;#39;s the code to do it:&lt;/p&gt;
&lt;div class="code"&gt;&lt;span class="Modifier"&gt;public&lt;/span&gt;&amp;nbsp;&lt;span class="ReferenceType"&gt;class&lt;/span&gt; ThreadSafeEnumerable&amp;lt;T&amp;gt; : IEnumerable&amp;lt;T&amp;gt;     &lt;br /&gt;{     &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="Modifier"&gt;private&lt;/span&gt;&amp;nbsp;&lt;span class="Modifier"&gt;readonly&lt;/span&gt; IEnumerable&amp;lt;T&amp;gt; original;     &lt;br /&gt;    &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="Modifier"&gt;public&lt;/span&gt; ThreadSafeEnumerable(IEnumerable&amp;lt;T&amp;gt; original)     &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {     &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="Keyword"&gt;this&lt;/span&gt;.original = original;     &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }     &lt;br /&gt;    &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="Modifier"&gt;public&lt;/span&gt; IEnumerator&amp;lt;T&amp;gt; GetEnumerator()     &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {     &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="Statement"&gt;return&lt;/span&gt;&amp;nbsp;&lt;span class="Keyword"&gt;new&lt;/span&gt; ThreadSafeEnumerator(original.GetEnumerator());     &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }     &lt;br /&gt;    &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; IEnumerator IEnumerable.GetEnumerator()     &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {     &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="Statement"&gt;return&lt;/span&gt; GetEnumerator();     &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }     &lt;br /&gt;    &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="Modifier"&gt;private&lt;/span&gt;&amp;nbsp;&lt;span class="Modifier"&gt;sealed&lt;/span&gt;&amp;nbsp;&lt;span class="ReferenceType"&gt;class&lt;/span&gt; ThreadSafeEnumerator : IEnumerator&amp;lt;T&amp;gt;     &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {     &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="Modifier"&gt;private&lt;/span&gt;&amp;nbsp;&lt;span class="Modifier"&gt;readonly&lt;/span&gt; IEnumerator&amp;lt;T&amp;gt; original;     &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="Modifier"&gt;private&lt;/span&gt;&amp;nbsp;&lt;span class="Modifier"&gt;readonly&lt;/span&gt;&amp;nbsp;&lt;span class="ReferenceType"&gt;object&lt;/span&gt; padlock = &lt;span class="Keyword"&gt;new&lt;/span&gt;&amp;nbsp;&lt;span class="ReferenceType"&gt;object&lt;/span&gt;();     &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="Modifier"&gt;private&lt;/span&gt;&amp;nbsp;&lt;span class="Modifier"&gt;readonly&lt;/span&gt; ThreadLocal&amp;lt;T&amp;gt; current = &lt;span class="Keyword"&gt;new&lt;/span&gt; ThreadLocal&amp;lt;T&amp;gt;();     &lt;br /&gt;    &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="Modifier"&gt;internal&lt;/span&gt; ThreadSafeEnumerator(IEnumerator&amp;lt;T&amp;gt; original)     &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {     &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="Keyword"&gt;this&lt;/span&gt;.original = original;     &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }     &lt;br /&gt;    &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="Modifier"&gt;public&lt;/span&gt;&amp;nbsp;&lt;span class="ValueType"&gt;bool&lt;/span&gt; MoveNext()     &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {     &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="Statement"&gt;lock&lt;/span&gt; (padlock)     &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {     &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="ValueType"&gt;bool&lt;/span&gt; ret = original.MoveNext();     &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="Statement"&gt;if&lt;/span&gt; (ret)     &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {     &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; current.Value = original.Current;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }     &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="Statement"&gt;return&lt;/span&gt; ret;     &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }     &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }     &lt;br /&gt;    &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="Modifier"&gt;public&lt;/span&gt; T Current     &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {     &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; get { &lt;span class="Statement"&gt;return&lt;/span&gt; current.Value; }     &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }     &lt;br /&gt;    &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="Modifier"&gt;public&lt;/span&gt;&amp;nbsp;&lt;span class="ValueType"&gt;void&lt;/span&gt; Dispose()     &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {     &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; original.Dispose();     &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; current.Dispose();     &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }     &lt;br /&gt;    &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="ReferenceType"&gt;object&lt;/span&gt; IEnumerator.Current     &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {     &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; get { &lt;span class="Statement"&gt;return&lt;/span&gt; Current; }     &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }     &lt;br /&gt;    &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="Modifier"&gt;public&lt;/span&gt;&amp;nbsp;&lt;span class="ValueType"&gt;void&lt;/span&gt; Reset()     &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {     &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="Statement"&gt;throw&lt;/span&gt;&amp;nbsp;&lt;span class="Keyword"&gt;new&lt;/span&gt; NotSupportedException();     &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }     &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }     &lt;br /&gt;} &lt;/div&gt;
&lt;p&gt;I&amp;#39;m going to say it one last time - we&amp;#39;re broken when it comes to disposal. There&amp;#39;s no way of &lt;em&gt;safely&lt;/em&gt; disposing of the original iterator at &amp;quot;just the right time&amp;quot; when everyone&amp;#39;s finished with it. Oh well.&lt;/p&gt;
&lt;p&gt;Other than that, it&amp;#39;s quite simple. This code has the serendipitous property of actually implementing IEnumerator&amp;lt;T&amp;gt; slightly better than C#-compiler-generated implementations from iterator blocks - if you call the Current property without having called MoveNext(), this will throw an InvalidOperationException, just as the documentation says it should. (It doesn&amp;#39;t do the same at the end, admittedly, but that&amp;#39;s fixable if we really wanted to be pedantic.&lt;/p&gt;
&lt;h3&gt;Conclusion&lt;/h3&gt;
&lt;p&gt;I found this an intriguing little problem. I think there are better ways of solving the bigger picture - a co-ordinator which takes care of disposing exactly once, and which possibly mediates the original iterator etc is probably the way forward... but I enjoyed thinking about the nitty gritty.&lt;/p&gt;
&lt;p&gt;Generally speaking, I prefer the first of these approaches. Thread local variables always feel like a bit of a grotty hack to me - they can be useful, but it&amp;#39;s better to avoid them if you can. It&amp;#39;s interesting to see how an interface can be inherently thread-friendly or not.&lt;/p&gt;
&lt;p&gt;One last word of warning - this code is &lt;em&gt;completely&lt;/em&gt; untested. It builds, and I can&amp;#39;t immediately see why it wouldn&amp;#39;t work, but I&amp;#39;m making no guarantees...&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1734632" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/Wacky+Ideas/default.aspx">Wacky Ideas</category><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/Parallelisation/default.aspx">Parallelisation</category><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/Stack+Overflow/default.aspx">Stack Overflow</category></item><item><title>API design: choosing between non-ideal options</title><link>http://msmvps.com/blogs/jon_skeet/archive/2009/09/14/api-design-choosing-between-non-ideal-options.aspx</link><pubDate>Mon, 14 Sep 2009 16:38:05 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1723277</guid><dc:creator>skeet</dc:creator><slash:comments>10</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/jon_skeet/rsscomments.aspx?PostID=1723277</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/jon_skeet/commentapi.aspx?PostID=1723277</wfw:comment><comments>http://msmvps.com/blogs/jon_skeet/archive/2009/09/14/api-design-choosing-between-non-ideal-options.aspx#comments</comments><description>&lt;p&gt;So, &lt;a href="http://code.google.com/p/unconstrained-melody"&gt;UnconstrainedMelody&lt;/a&gt; is coming on quite nicely. It now has quite a few useful options for flags enums, &amp;quot;normal enums&amp;quot; and delegates. However, there are two conflicting limitations which leave a couple of options. (Other related answers on Stack Overflow have suggested alternative approaches, basically.)&lt;/p&gt;  &lt;p&gt;Currently, most of the enums code is in two classes: Flags and Enums. Both are non-generic: the methods within them are generic methods, so they have type parameters (and constraints). The main benefit of this is that generic type inference only applies to generic methods, and I &lt;em&gt;definitely&lt;/em&gt; want that for extension methods and anywhere else it makes sense.&lt;/p&gt;  &lt;p&gt;The drawback is that properties can&amp;#39;t be generic. That means my API is entirely expressed in terms of methods, which can be a pain. The option to work around this is to have a generic type which properties in. This adds confusion and guesswork - what call is where?&lt;/p&gt;  &lt;p&gt;To recap, the options are:&lt;/p&gt;  &lt;div class="code"&gt;&lt;span class="InlineComment"&gt;// Option 1 (current): all methods in a nongeneric class:&lt;/span&gt;    &lt;br /&gt;&lt;span class="InlineComment"&gt;// Some calls which are logically properties end up&lt;/span&gt;    &lt;br /&gt;&lt;span class="InlineComment"&gt;// as methods...&lt;/span&gt;    &lt;br /&gt;IList&amp;lt;Foo&amp;gt; foos = Enums.GetValues&amp;lt;Foo&amp;gt;();    &lt;br /&gt;&lt;span class="InlineComment"&gt;// Type infererence for extenion methods&lt;/span&gt;    &lt;br /&gt;&lt;span class="InlineComment"&gt;// Note that we couldn&amp;#39;t have a Description property&lt;/span&gt;    &lt;br /&gt;&lt;span class="InlineComment"&gt;// as we don&amp;#39;t have extension properties&lt;/span&gt;    &lt;br /&gt;&lt;span class="ReferenceType"&gt;string&lt;/span&gt; firstDescription = foos[0].GetDescription();    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;br /&gt;&lt;span class="InlineComment"&gt;// Option 2: Use just a generic type:&lt;/span&gt;    &lt;br /&gt;&lt;span class="InlineComment"&gt;// Now we can use a property...&lt;/span&gt;    &lt;br /&gt;IList&amp;lt;Foo&amp;gt; foos = Enums&amp;lt;Foo&amp;gt;.Values;    &lt;br /&gt;&lt;span class="InlineComment"&gt;// But we can&amp;#39;t use type inference&lt;/span&gt;    &lt;br /&gt;&lt;span class="ReferenceType"&gt;string&lt;/span&gt; firstDescription = Enums&amp;lt;Foo&amp;gt;.GetDescription(foos[0]);    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;br /&gt;&lt;span class="InlineComment"&gt;// Option 3: Use a mixture (Enums and Enums&amp;lt;T&amp;gt;):&lt;/span&gt;    &lt;br /&gt;IList&amp;lt;Foo&amp;gt; foos = Enums&amp;lt;Foo&amp;gt;.Values;    &lt;br /&gt;&lt;span class="InlineComment"&gt;// All looks good...&lt;/span&gt;    &lt;br /&gt;&lt;span class="ReferenceType"&gt;string&lt;/span&gt; firstDescription = foos[0].GetDescription();    &lt;br /&gt;&lt;span class="InlineComment"&gt;// ... but the user has to know when to use which class&lt;/span&gt; &lt;/div&gt;  &lt;p&gt;All of these are somewhat annoying. If we &lt;em&gt;only &lt;/em&gt;put extension methods into the nongeneric class, then I guess users would never need to really think about that - they&amp;#39;d pretty much always be calling the methods via the extension method syntactic sugar anyway. It still feels like a pretty arbitrary split though.&lt;/p&gt;  &lt;p&gt;Any thoughts? Which is more important - conceptual complexity, or the idiomatic client code you end up with once that complexity has been mastered? Is it reasonable to make design decisions like this around what is essentially a single piece of syntactic sugar (extension methods)?&lt;/p&gt;  &lt;p&gt;(By the way, if anyone ever wanted justification for extension properties, I think this is a good example... Description feels like it really &lt;em&gt;should&lt;/em&gt; be a property.)&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1723277" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/Stack+Overflow/default.aspx">Stack Overflow</category><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/Evil+Code/default.aspx">Evil Code</category></item><item><title>Generic constraints for enums and delegates</title><link>http://msmvps.com/blogs/jon_skeet/archive/2009/09/10/generic-constraints-for-enums-and-delegates.aspx</link><pubDate>Thu, 10 Sep 2009 20:09:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1722426</guid><dc:creator>skeet</dc:creator><slash:comments>56</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/jon_skeet/rsscomments.aspx?PostID=1722426</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/jon_skeet/commentapi.aspx?PostID=1722426</wfw:comment><comments>http://msmvps.com/blogs/jon_skeet/archive/2009/09/10/generic-constraints-for-enums-and-delegates.aspx#comments</comments><description>&lt;p&gt;As most readers probably know, C# prohibits generic type constraints from referring to System.Object, System.Enum, System.Array, System.Delegate and System.ValueType. In other words, this method declaration is illegal:&lt;/p&gt;
&lt;div class="code"&gt;&lt;span class="Modifier"&gt;public&lt;/span&gt;&amp;nbsp;&lt;span class="Modifier"&gt;static&lt;/span&gt; T[]GetValues&amp;lt;T&amp;gt;() &lt;span class="Linq"&gt;where&lt;/span&gt; T : struct, System.Enum&lt;br /&gt;{     &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="Statement"&gt;return&lt;/span&gt; (T[]) Enum.GetValues(&lt;span class="Keyword"&gt;typeof&lt;/span&gt;(T));     &lt;br /&gt;} &lt;/div&gt;
&lt;p&gt;This is a pity, as such a method could be useful. (In fact there are better things we can do... such as returning a read-only collection. That way we don&amp;#39;t have to create a new array each time the method is called.) As far as I can tell, there is no reason why this should be prohibited. Eric Lippert has stated that he believes &lt;a href="http://stackoverflow.com/questions/1331739/enum-type-constraints-in-c/1331811#1331811"&gt;the CLR doesn&amp;#39;t support this&lt;/a&gt; - but I think he&amp;#39;s wrong. I can&amp;#39;t remember the last time I had cause to believe Eric to be wrong about something, and I&amp;#39;m somewhat nervous of even mentioning it, but section 10.1.7 of the CLI spec (&lt;a href="http://www.ecma-international.org/publications/standards/Ecma-335.htm"&gt;ECMA-335&lt;/a&gt;) partition II (p40) &lt;em&gt;specifically&lt;/em&gt; gives examples of type parameter constraints involving System.Delegate and System.Enum. It introduces the table with &amp;quot;The following table shows the valid combinations of type and special constraints for a representative set of types.&amp;quot; It was only due to reading this table that I realized that the value type constraint on the above is required (or a constructor constraint would do equally well) - otherwise System.Enum itself satisfies the constraint, which would be a Bad Thing.&lt;/p&gt;
&lt;p&gt;It&amp;#39;s possible (but unlikely) that the CLI doesn&amp;#39;t fully implement this part of the CLR spec. I&amp;#39;m hoping that Eric&amp;#39;s just wrong on this occasion, and that actually there&amp;#39;s nothing to stop the C# language from allowing such constraints in the future. (It would be nice to get keyword support, such that a constraint of &amp;quot;T : enum&amp;quot; would be equivalent to the above, but hey...)&lt;/p&gt;
&lt;p&gt;The good news is that ilasm/ildasm have no problem with this. The better news is that if you add a reference to a library which uses those constraints, the C# compiler applies them sensibly, as far as I can tell...&lt;/p&gt;
&lt;h3&gt;Introducing UnconstrainedMelody&lt;/h3&gt;
&lt;p&gt;(Okay, the name will almost surely have to change. But I like the idea of it removing the constraints of C# around which constraints are valid... and yet still being in the key of C#. Better suggestions welcome.)&lt;/p&gt;
&lt;p&gt;I have a plan - I want to write a utility library which does useful things for enums and delegates (and arrays if I can think of anything sensible to do with them). It will be written in C#, with methods like this:&lt;/p&gt;
&lt;div class="code"&gt;&lt;span class="Modifier"&gt;public&lt;/span&gt;&amp;nbsp;&lt;span class="Modifier"&gt;static&lt;/span&gt; T[]GetValues&amp;lt;T&amp;gt;() &lt;span class="Linq"&gt;where&lt;/span&gt; T : struct, IEnumConstraint&lt;br /&gt;{     &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="Statement"&gt;return&lt;/span&gt; (T[]) Enum.GetValues(&lt;span class="Keyword"&gt;typeof&lt;/span&gt;(T));     &lt;br /&gt;} &lt;/div&gt;
&lt;p&gt;(IEnumConstraint has to be an interface of course, as otherwise the constraint would be invalid.)&lt;/p&gt;
&lt;p&gt;As a post-build step, I will:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Run ildasm on the resulting binary&lt;/li&gt;
&lt;li&gt;Replace every constraint using EnumConstraint with System.Enum&lt;/li&gt;
&lt;li&gt;Run ilasm to build the binary again&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If anyone has a &lt;em&gt;simple&lt;/em&gt; binary rewriter (I&amp;#39;ve looked at &lt;a href="http://postsharp.org"&gt;PostSharp&lt;/a&gt; and &lt;a href="http://cciast.codeplex.com/license"&gt;CCI&lt;/a&gt;; both look &lt;em&gt;way&lt;/em&gt; more complicated than the above) which would do this, that would be great. Otherwise ildasm/ilasm will be fine. It&amp;#39;s not like &lt;em&gt;consumers&lt;/em&gt; will need to perform this step.&lt;/p&gt;
&lt;p&gt;As soon as the name is finalized I&amp;#39;ll add a project on Google Code. Once the infrastructure is in place, adding utility methods should be very straightforward. Suggestions for utility methods would be useful, or just join the project when it&amp;#39;s up and running.&lt;/p&gt;
&lt;p&gt;Am I being silly? Have I overlooked something?&lt;/p&gt;
&lt;h3&gt;A couple of hours later...&lt;/h3&gt;
&lt;p&gt;Okay, I decided not to wait for a better name. The first cut - which does basically nothing but validate the idea, and the fact that I can still unit test it - is in. The &lt;a href="http://code.google.com/p/unconstrained-melody"&gt;UnconstrainedMelody Google Code project&lt;/a&gt; is live!&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1722426" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/Wacky+Ideas/default.aspx">Wacky Ideas</category><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/Stack+Overflow/default.aspx">Stack Overflow</category></item><item><title>Recent activities</title><link>http://msmvps.com/blogs/jon_skeet/archive/2009/09/04/recent-activities.aspx</link><pubDate>Thu, 03 Sep 2009 23:08:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1720570</guid><dc:creator>skeet</dc:creator><slash:comments>15</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/jon_skeet/rsscomments.aspx?PostID=1720570</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/jon_skeet/commentapi.aspx?PostID=1720570</wfw:comment><comments>http://msmvps.com/blogs/jon_skeet/archive/2009/09/04/recent-activities.aspx#comments</comments><description>&lt;p&gt;It&amp;#39;s been a little while since I&amp;#39;ve blogged, and quite a lot has been going on. In fact, there are a few things I&amp;#39;d have blogged about already if it weren&amp;#39;t for &amp;quot;things&amp;quot; getting in the way.&lt;/p&gt;
&lt;p&gt;Rather than writing a whole series of very short blog posts, I thought I&amp;#39;d wrap them all up here...&lt;/p&gt;
&lt;h3&gt;C# in Depth: next MEAP drop available soon - Code Contracts&lt;/h3&gt;
&lt;p&gt;Thanks to everyone who gave feedback on my &lt;a href="http://msmvps.com/blogs/jon_skeet/archive/2009/08/05/tricky-decisions-code-contracts-and-parallel-extensions-in-c-in-depth-2nd-edition.aspx"&gt;writing dilemma&lt;/a&gt;. For the moment, the plan is to have a whole chapter about Code Contracts, but &lt;em&gt;not&lt;/em&gt; include a chapter about Parallel Extensions. My argument for making this decision is that Code Contracts really change the &lt;em&gt;feel&lt;/em&gt; of the code, making it almost like a language feature - and its applicability is almost ubiquitous, unlike PFX.&lt;/p&gt;
&lt;p&gt;I &lt;em&gt;may&lt;/em&gt; write a PFX chapter as a separate download, but I&amp;#39;m sensitive to those who (like me) appreciate slim books. I don&amp;#39;t want to &amp;quot;bulk out&amp;quot; the book with extra topics.&lt;/p&gt;
&lt;p&gt;The Code Contracts chapter is in the final stages before becoming available to MEAP subscribers. (It&amp;#39;s been &amp;quot;nearly ready&amp;quot; for a couple of weeks, but I&amp;#39;ve been on holiday, amongst other things.) After that, I&amp;#39;m going back to the existing chapters and revising them.&lt;/p&gt;
&lt;h3&gt;Talking in Dublin - C# 4 and Parallel Extensions&lt;/h3&gt;
&lt;p&gt;Last week I gave two talks in Dublin at &lt;a href="http://epicenter.ie/"&gt;Epicenter&lt;/a&gt;. One was on C# 4, and the other on Code Contracts and Parallel Extensions. Both are now available in a slightly odd form on the &lt;a href="http://csharpindepth.com/Talks.aspx"&gt;Talks page&lt;/a&gt; of the C# in Depth web site. I no longer write &amp;quot;formal&amp;quot; PowerPoint slides, so the downloads are for simple bullet points of text, along with silly hand-drawn slides. No code yet - I want to tidy it up a bit before including it.&lt;/p&gt;
&lt;h3&gt;Podcasting with The Connected Show&lt;/h3&gt;
&lt;p&gt;I recently recorded a &lt;a href="http://www.lyalin.com/Blog/archive/2009/09/01/connected-show-15-ndash-c-4-it-ainrsquot-that-complex.aspx"&gt;podcast episode&lt;/a&gt; with &lt;a href="http://www.connectedshow.com/"&gt;The Connected Show&lt;/a&gt;. I&amp;#39;m &amp;quot;on&amp;quot; for the second 2/3 of the show - about an hour of me blathering on about the new features of C# 4. If you can understand generic variance just by listening to me talking about it, you&amp;#39;re a smart cookie ;)&lt;/p&gt;
&lt;p&gt;(Oh, and if you like it, please express your amusement on &lt;a href="http://digg.com/microsoft/Connected_Show_15_Jon_Skeet_goes_DEEP_on_C_4_0"&gt;Digg&lt;/a&gt; / &lt;a href="http://www.dzone.com/links/connected_show_15_jon_skeet_goes_deep_on_c_40.html"&gt;DZone&lt;/a&gt; / &lt;a href="http://dotnetshoutout.com/Connected-Show-15-Jon-Skeet-goes-DEEP-on-C-40"&gt;Shout&lt;/a&gt; / &lt;a href="http://www.dotnetkicks.com/csharp/Connected_Show_15_Jon_Skeet_goes_DEEP_on_C_4_0"&gt;Kicks&lt;/a&gt;.)&lt;/p&gt;
&lt;h3&gt;Finishing up with Functional Programming for the Real World&lt;/h3&gt;
&lt;p&gt;Well, this hasn&amp;#39;t been taking much of my time recently (I bowed out of all the indexing etc!) but &lt;a href="http://manning.com/petricek"&gt;Functional Programming for the Real World&lt;/a&gt; is nearly ready to go. Hard copy should be available in the next couple of months... it&amp;#39;ll be really nice to see how it fares. Much kudos to Tomas for all his hard work - I&amp;#39;ve really just been helping out a little.&lt;/p&gt;
&lt;h3&gt;Starting on Groovy in Action, 2nd edition&lt;/h3&gt;
&lt;p&gt;No sooner does one book finish than another one starts. The &lt;a href="http://manning.com/koenig2/"&gt;second edition of Groovy in Action&lt;/a&gt; is in the works, which should prove interesting. To be honest, I haven&amp;#39;t played with Groovy much since the first edition of the book was finished, so it&amp;#39;ll be interesting to see what&amp;#39;s happened to the language in the meantime. I&amp;#39;ll be applying the same sort of spit and polish that I did in the first edition, and asking appropriately ignorant questions of the other authors.&lt;/p&gt;
&lt;h3&gt;Tech Reviewing C# 4.0 in a Nutshell&lt;/h3&gt;
&lt;p&gt;&lt;a href="http://msmvps.com/blogs/jon_skeet/archive/2008/03/31/book-review-c-3-0-in-a-nutshell.aspx"&gt;I liked C# 3.0 in a Nutshell&lt;/a&gt;, and I feel honoured that Joe asked me to be a tech reviewer for the next edition, which promises to be even better. There&amp;#39;s not a lot more I can say about it at the moment, other than it&amp;#39;ll be out in 2010 - and I still feel that C# in Depth is a good companion book.&lt;/p&gt;
&lt;h3&gt;MoreLINQ now at 1.0 beta&lt;/h3&gt;
&lt;p&gt;A while ago I started the &lt;a href="http://code.google.com/p/morelinq/"&gt;MoreLINQ project&lt;/a&gt;, and it gained some developers with more time than I&amp;#39;ve got available :) Basically the idea is to add some more useful LINQ extension methods to LINQ to Object. Thanks to Atif Aziz, the first beta version has been released. This doesn&amp;#39;t mean we&amp;#39;re &amp;quot;done&amp;quot; though - just that we think we&amp;#39;ve got something useful. Any suggestions for other operators would be welcome.&lt;/p&gt;
&lt;h3&gt;Manning Pop Quiz and discounts&lt;/h3&gt;
&lt;p&gt;While I&amp;#39;m plugging books etc, it&amp;#39;s worth mentioning the &lt;a href="http://www.manning.com/popquiz/"&gt;Manning Pop Quiz&lt;/a&gt; - multiple choice questions on a wide variety of topics. Fabulous prizes available, as well as one-day discounts:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Monday, Sept 7th: 50% of all print books (code: pop0907)&lt;/li&gt;
&lt;li&gt;Monday, Sept 14: 50% off all ebooks&amp;nbsp; (code: pop0914)&lt;/li&gt;
&lt;li&gt;Thursday, Sept 17: $25 for C# in Depth, 2nd Edition MEAP print version (code: pop0917) + C# Pop Quiz question&lt;/li&gt;
&lt;li&gt;Monday, Sept 21: 50% off all books&amp;nbsp; (code: pop0921)&lt;/li&gt;
&lt;li&gt;Thursday, Sept 24: $12 for C# in Depth, 2nd Edition MEAP ebook (code: pop0924) + another C# Pop Quiz question&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Future speaking engagements&lt;/h3&gt;
&lt;p&gt;On September 16th I&amp;#39;m going to be speaking to &lt;a href="http://edgeug.net/"&gt;Edge UG&lt;/a&gt; (formerly Vista Squad) in London about Code Contracts and Parallel Extensions. I&amp;#39;m already &lt;em&gt;very&lt;/em&gt; much looking forward to the &lt;a href="http://stackoverflow.carsonified.com/events/london/"&gt;Stack Overflow DevDays London conference&lt;/a&gt; on October 28th, at which I&amp;#39;ll be talking about how humanity has screwed up computing.&lt;/p&gt;
&lt;h3&gt;Future potential blog posts&lt;/h3&gt;
&lt;p&gt;Some day I may get round to writing about:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Revisiting StaticRandom with ThreadLocal&amp;lt;T&amp;gt;&lt;/li&gt;
&lt;li&gt;Volatile doesn&amp;#39;t mean what I thought it did&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;There&amp;#39;s a lot more writing than coding in that list... I&amp;#39;d like to spend some more time on &lt;a href="http://code.google.com/p/minibench/"&gt;MiniBench&lt;/a&gt; at some point, but you know what deadlines are like.&lt;/p&gt;
&lt;p&gt;Anyway, that&amp;#39;s what I&amp;#39;ve been up to and what I&amp;#39;ll be doing for a little while...&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1720570" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/General/default.aspx">General</category><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/Books/default.aspx">Books</category><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/C_2300_+4/default.aspx">C# 4</category><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/Parallelisation/default.aspx">Parallelisation</category><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/Speaking+engagements/default.aspx">Speaking engagements</category><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/Stack+Overflow/default.aspx">Stack Overflow</category></item><item><title>Faking COM to fool the C# compiler</title><link>http://msmvps.com/blogs/jon_skeet/archive/2009/07/07/faking-com-to-fool-the-c-compiler.aspx</link><pubDate>Tue, 07 Jul 2009 22:28:46 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1698645</guid><dc:creator>skeet</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/jon_skeet/rsscomments.aspx?PostID=1698645</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/jon_skeet/commentapi.aspx?PostID=1698645</wfw:comment><comments>http://msmvps.com/blogs/jon_skeet/archive/2009/07/07/faking-com-to-fool-the-c-compiler.aspx#comments</comments><description>&lt;p&gt;C# 4 has some great features to make programming against COM components &lt;strike&gt;bearable&lt;/strike&gt; fun and exciting. In particular:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;PIA linking allows you to embed just the relevant bits of the Primary Interop Assembly into your own assembly, so the PIA isn&amp;#39;t actually required at execution time &lt;/li&gt;    &lt;li&gt;Named arguments and optional parameters make life &lt;em&gt;much&lt;/em&gt; simpler for APIs like Office which are full of methods with gazillions of parameters &lt;/li&gt;    &lt;li&gt;&amp;quot;ref&amp;quot; removal allows you to pass an argument by value even though the parameter is a by-reference parameter (COM only, folks - don&amp;#39;t worry!) &lt;/li&gt;    &lt;li&gt;Dynamic typing allows you to remove a load of casts by converting every parameter and return type of &amp;quot;object&amp;quot; into &amp;quot;dynamic&amp;quot; (if you&amp;#39;re using PIA linking) &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;I&amp;#39;m currently writing about these features for &lt;a href="http://manning.com/skeet2"&gt;the book&lt;/a&gt; (don&amp;#39;t forget to &lt;a href="http://msmvps.com/blogs/jon_skeet/archive/2009/07/06/books-going-cheap.aspx"&gt;buy it cheap on Friday&lt;/a&gt;) but I&amp;#39;m not really a COM person. I want to be able to see these compiler features at work against a really simple type. Unfortunately, these really are COM-specific features... so we&amp;#39;re going to have to persuade COM that the type really is a COM type.&lt;/p&gt;  &lt;p&gt;I got slightly stuck on this first, but thanks to &lt;a href="http://stackoverflow.com/questions/1093536"&gt;the power of Stack Overflow&lt;/a&gt;, I now have a reasonably complete demo &amp;quot;fake&amp;quot; COM type. It doesn&amp;#39;t do a lot, and in particular it doesn&amp;#39;t have any events, but it&amp;#39;s enough to show the compiler features:&lt;/p&gt;  &lt;div class="code"&gt;&lt;span class="Namespace"&gt;using&lt;/span&gt; System;     &lt;br /&gt;&lt;span class="Namespace"&gt;using&lt;/span&gt; System.Runtime.InteropServices;     &lt;br /&gt;    &lt;br /&gt;&lt;span class="InlineComment"&gt;// Required for linking into another assembly (C# 4)&lt;/span&gt;     &lt;br /&gt;[assembly:Guid(&lt;span class="String"&gt;&amp;quot;86ca55e4-9d4b-462b-8ec8-b62e993aeb64&amp;quot;&lt;/span&gt;)]     &lt;br /&gt;[assembly:ImportedFromTypeLib(&lt;span class="String"&gt;&amp;quot;fake.tlb&amp;quot;&lt;/span&gt;)]     &lt;br /&gt;    &lt;br /&gt;&lt;span class="Namespace"&gt;namespace&lt;/span&gt; FakeCom     &lt;br /&gt;{     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; [Guid(&lt;span class="String"&gt;&amp;quot;c3cb8098-0b8f-4a9a-9772-788d340d6ae0&amp;quot;&lt;/span&gt;)]     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; [ComImport, CoClass(&lt;span class="Keyword"&gt;typeof&lt;/span&gt;(FakeImpl))]     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Modifier"&gt;public&lt;/span&gt;&amp;#160;&lt;span class="ReferenceType"&gt;interface&lt;/span&gt; FakeComponent     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="ReferenceType"&gt;object&lt;/span&gt; MakeMeDynamic(&lt;span class="ReferenceType"&gt;object&lt;/span&gt; arg);     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="ValueType"&gt;void&lt;/span&gt; Foo([Optional] &lt;span class="MethodParameter"&gt;ref&lt;/span&gt;&amp;#160;&lt;span class="ValueType"&gt;int&lt;/span&gt; x,     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; [Optional] &lt;span class="MethodParameter"&gt;ref&lt;/span&gt;&amp;#160;&lt;span class="ReferenceType"&gt;string&lt;/span&gt; y);     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }     &lt;br /&gt;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; [Guid(&lt;span class="String"&gt;&amp;quot;734e6105-a20f-4748-a7de-2c83d7e91b04&amp;quot;&lt;/span&gt;)]     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Modifier"&gt;public&lt;/span&gt;&amp;#160;&lt;span class="ReferenceType"&gt;class&lt;/span&gt; FakeImpl {}     &lt;br /&gt;} &lt;/div&gt;  &lt;p&gt;We have an interface representing our COM type, and a class which the interface claims will implement it. Fortunately the compiler doesn&amp;#39;t actually check that, so we can get away with leaving it entirely unimplemented. It&amp;#39;s also worth noting that our optional parameters can be by-reference parameters (which you can&amp;#39;t normally do in C# 4) and we haven&amp;#39;t given them any default values (as those are ignored for COM anyway).&lt;/p&gt;  &lt;p&gt;This is compiled just like any other assembly: &lt;/p&gt;  &lt;div class="code"&gt;csc /target:library FakeCom.cs &lt;/div&gt;  &lt;p&gt;Then we get to use it with a test program: &lt;/p&gt;  &lt;div class="code"&gt;&lt;span class="Namespace"&gt;using&lt;/span&gt; FakeCom;    &lt;br /&gt;    &lt;br /&gt;&lt;span class="ReferenceType"&gt;class&lt;/span&gt; Test    &lt;br /&gt;{    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Modifier"&gt;static&lt;/span&gt;&amp;#160;&lt;span class="ValueType"&gt;void&lt;/span&gt; Main()    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="InlineComment"&gt;// Yes, that is calling a &amp;quot;constructor&amp;quot; on an interface&lt;/span&gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; FakeComponent com = &lt;span class="Keyword"&gt;new&lt;/span&gt; FakeComponent();    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="InlineComment"&gt;// The boring old fashioned way of calling a method&lt;/span&gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="ValueType"&gt;int&lt;/span&gt; i = 0;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="ReferenceType"&gt;string&lt;/span&gt; j = &lt;span class="Keyword"&gt;null&lt;/span&gt;;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; com.Foo(&lt;span class="MethodParameter"&gt;ref&lt;/span&gt; i, &lt;span class="MethodParameter"&gt;ref&lt;/span&gt; j);    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="InlineComment"&gt;// Look ma, no ref!&lt;/span&gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; com.Foo(10, &lt;span class="String"&gt;&amp;quot;Wow!&amp;quot;&lt;/span&gt;);    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="InlineComment"&gt;// Who cares about parameter ordering?&lt;/span&gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; com.Foo(y: &lt;span class="String"&gt;&amp;quot;Not me&amp;quot;&lt;/span&gt;, x: 0);    &lt;br /&gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="InlineComment"&gt;// And the parameters are optional too&lt;/span&gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; com.Foo();    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="InlineComment"&gt;// The line below only works when linked rather than&lt;/span&gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="InlineComment"&gt;// referenced, as otherwise you need a cast.&lt;/span&gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="InlineComment"&gt;// The compiler treats it as if it both takes and&lt;/span&gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="InlineComment"&gt;// returns a dynamic value.&lt;/span&gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="ReferenceType"&gt;string&lt;/span&gt; value = com.MakeMeDynamic(10);    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }    &lt;br /&gt;} &lt;/div&gt;  &lt;p&gt;This is compiled either in the old &amp;quot;deploy the PIA as well&amp;quot; way (after adding a cast in the last line): &lt;/p&gt;  &lt;div class="code"&gt;csc /r:FakeCom.dll Test.cs &lt;/div&gt;  &lt;p&gt;... or by linking the PIA instead:&lt;/p&gt;  &lt;div class="code"&gt;csc /l:FakeCom.dll Test.cs &lt;/div&gt;  &lt;p&gt;(The difference is just using &lt;code&gt;/l&lt;/code&gt; instead of &lt;code&gt;/r&lt;/code&gt;.)&lt;/p&gt;  &lt;p&gt;When the test code is compiled as a reference, it decompiles in Reflector to this (I&amp;#39;ve added whitespace for clarity):&lt;/p&gt;  &lt;div class="code"&gt;&lt;span class="Modifier"&gt;private&lt;/span&gt;&amp;#160;&lt;span class="Modifier"&gt;static&lt;/span&gt;&amp;#160;&lt;span class="ValueType"&gt;void&lt;/span&gt; Main()    &lt;br /&gt;{    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; FakeComponent component = (FakeComponent) &lt;span class="Keyword"&gt;new&lt;/span&gt; FakeImpl();    &lt;br /&gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="ValueType"&gt;int&lt;/span&gt; x = 0;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="ReferenceType"&gt;string&lt;/span&gt; y = &lt;span class="Keyword"&gt;null&lt;/span&gt;;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; component.Foo(&lt;span class="MethodParameter"&gt;ref&lt;/span&gt; x, &lt;span class="MethodParameter"&gt;ref&lt;/span&gt; y);    &lt;br /&gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="ValueType"&gt;int&lt;/span&gt; num2 = 10;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="ReferenceType"&gt;string&lt;/span&gt; str3 = &lt;span class="String"&gt;&amp;quot;Wow!&amp;quot;&lt;/span&gt;;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; component.Foo(&lt;span class="MethodParameter"&gt;ref&lt;/span&gt; num2, &lt;span class="MethodParameter"&gt;ref&lt;/span&gt; str3);    &lt;br /&gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="ReferenceType"&gt;string&lt;/span&gt; str4 = &lt;span class="String"&gt;&amp;quot;Not me&amp;quot;&lt;/span&gt;;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="ValueType"&gt;int&lt;/span&gt; num3 = 0;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; component.Foo(&lt;span class="MethodParameter"&gt;ref&lt;/span&gt; num3, &lt;span class="MethodParameter"&gt;ref&lt;/span&gt; str4);    &lt;br /&gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="ValueType"&gt;int&lt;/span&gt; num4 = 0;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="ReferenceType"&gt;string&lt;/span&gt; str5 = &lt;span class="Keyword"&gt;null&lt;/span&gt;;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; component.Foo(&lt;span class="MethodParameter"&gt;ref&lt;/span&gt; num4, &lt;span class="MethodParameter"&gt;ref&lt;/span&gt; str5);    &lt;br /&gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="ReferenceType"&gt;string&lt;/span&gt; str2 = (&lt;span class="ReferenceType"&gt;string&lt;/span&gt;) component.MakeMeDynamic(10);    &lt;br /&gt;} &lt;/div&gt;  &lt;p&gt;Note how the compiler has created local variables to pass by reference; any changes to the parameter are ignored when the method returns. (If you actually pass a variable by reference, the compiler won&amp;#39;t take that away, however.) &lt;/p&gt;  &lt;p&gt;When the code is linked instead, the middle section is the same, but the construction and the line calling &lt;code&gt;MakeMeDynamic&lt;/code&gt; are very different:&lt;/p&gt;  &lt;div class="code"&gt;&lt;span class="Modifier"&gt;private&lt;/span&gt;&amp;#160;&lt;span class="Modifier"&gt;static&lt;/span&gt;&amp;#160;&lt;span class="ValueType"&gt;void&lt;/span&gt; Main()    &lt;br /&gt;{    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; FakeComponent component = (FakeComponent) Activator.CreateInstance(Type.GetTypeFromCLSID    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; (&lt;span class="Keyword"&gt;new&lt;/span&gt; Guid(&lt;span class="String"&gt;&amp;quot;734E6105-A20F-4748-A7DE-2C83D7E91B04&amp;quot;&lt;/span&gt;)));    &lt;br /&gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="InlineComment"&gt;// Middle bit as before&lt;/span&gt;    &lt;br /&gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Statement"&gt;if&lt;/span&gt; (&amp;lt;Main&amp;gt;o__SiteContainer6.&amp;lt;&amp;gt;p__Site7 == &lt;span class="Keyword"&gt;null&lt;/span&gt;)    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;Main&amp;gt;o__SiteContainer6.&amp;lt;&amp;gt;p__Site7 = CallSite&amp;lt;Func&amp;lt;CallSite, &lt;span class="ReferenceType"&gt;object&lt;/span&gt;, &lt;span class="ReferenceType"&gt;string&lt;/span&gt;&amp;gt;&amp;gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; .Create(&lt;span class="Keyword"&gt;new&lt;/span&gt; CSharpConvertBinder    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; (&lt;span class="Keyword"&gt;typeof&lt;/span&gt;(&lt;span class="ReferenceType"&gt;string&lt;/span&gt;),&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; CSharpConversionKind.ImplicitConversion, &lt;span class="Keyword"&gt;false&lt;/span&gt;));    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="ReferenceType"&gt;string&lt;/span&gt; str2 = &amp;lt;Main&amp;gt;o__SiteContainer6.&amp;lt;&amp;gt;p__Site7.Target.Invoke    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; (&amp;lt;Main&amp;gt;o__SiteContainer6.&amp;lt;&amp;gt;p__Site7, component.MakeMeDynamic(10));    &lt;br /&gt;} &lt;/div&gt;  &lt;p&gt;The interface is embedded in the generated assembly, but with a slightly different set of attributes:&lt;/p&gt;  &lt;div class="code"&gt;[ComImport, CompilerGenerated]   &lt;br /&gt;[Guid(&lt;span class="String"&gt;&amp;quot;C3CB8098-0B8F-4A9A-9772-788D340D6AE0&amp;quot;&lt;/span&gt;), TypeIdentifier]    &lt;br /&gt;&lt;span class="Modifier"&gt;public&lt;/span&gt;&amp;#160;&lt;span class="ReferenceType"&gt;interface&lt;/span&gt; FakeComponent    &lt;br /&gt;{    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="ReferenceType"&gt;object&lt;/span&gt; MakeMeDynamic(&lt;span class="ReferenceType"&gt;object&lt;/span&gt; arg);    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="ValueType"&gt;void&lt;/span&gt; Foo([Optional] &lt;span class="MethodParameter"&gt;ref&lt;/span&gt;&amp;#160;&lt;span class="ValueType"&gt;int&lt;/span&gt; x, [Optional] &lt;span class="MethodParameter"&gt;ref&lt;/span&gt;&amp;#160;&lt;span class="ReferenceType"&gt;string&lt;/span&gt; y);    &lt;br /&gt;} &lt;/div&gt;  &lt;p&gt;The class isn&amp;#39;t present at all.&lt;/p&gt;  &lt;p&gt;I should point out that doing this has no practical benefit in real code - but the ability to mess around with a pseudo-COM type rather than having to find a &lt;em&gt;real&lt;/em&gt; one with the exact members I want will make it a lot easier to try a few corner cases for the book.&lt;/p&gt;  &lt;p&gt;So, not a terribly productive evening in terms of getting actual writing done, but interesting nonetheless...&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1698645" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/Wacky+Ideas/default.aspx">Wacky Ideas</category><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/Books/default.aspx">Books</category><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/C_2300_+4/default.aspx">C# 4</category><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/Stack+Overflow/default.aspx">Stack Overflow</category></item><item><title>Reasons for voting on questions and answers</title><link>http://msmvps.com/blogs/jon_skeet/archive/2009/05/20/reasons-for-voting-on-questions-and-answers.aspx</link><pubDate>Wed, 20 May 2009 14:21:12 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1692775</guid><dc:creator>skeet</dc:creator><slash:comments>23</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/jon_skeet/rsscomments.aspx?PostID=1692775</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/jon_skeet/commentapi.aspx?PostID=1692775</wfw:comment><comments>http://msmvps.com/blogs/jon_skeet/archive/2009/05/20/reasons-for-voting-on-questions-and-answers.aspx#comments</comments><description>&lt;p&gt;I&amp;#39;ve recently been involved in a few discussions around voting on &lt;a href="http://stackoverflow.com"&gt;Stack Overflow&lt;/a&gt;, and I think my own &amp;quot;policy&amp;quot; around it may be different to that of others. I thought it would be worth sharing why I personally vote items up or down, and hear your thoughts too. This blog may not be the &lt;em&gt;ideal&lt;/em&gt; venue for such a post, but until such time as we have a real &amp;quot;meta&amp;quot; site for Stack Overflow (such as &lt;a href="http://stackoverflowoverflow.com/"&gt;Stack Overflow Overflow&lt;/a&gt;) I can&amp;#39;t think of anywhere better to write about it. Readers who are only interested in coding should move on; I promise not to include anything about code in the rest of this post.&lt;/p&gt;  &lt;p&gt;I&amp;#39;m going to assume that anyone who&amp;#39;s read this far is at least somewhat familiar with the logistics of Stack Overflow - in particular, &lt;em&gt;how&lt;/em&gt; one votes and the effects on reputation. I&amp;#39;ll use the word &amp;quot;post&amp;quot; here to mean either a question or an answer.&lt;/p&gt;  &lt;p&gt;I&amp;#39;d like to stress that this is in no way meant to be seen as an &amp;quot;official&amp;quot; voting guide - just how &lt;em&gt;I&lt;/em&gt; happen to think.&lt;/p&gt;  &lt;h3&gt;Why vote?&lt;/h3&gt;  &lt;p&gt;There are two &amp;quot;audiences&amp;quot; for a vote in my view: the author of the post and the community who is reading the post and looking at the vote tally. The author can tell what votes they&amp;#39;ve received using the reputation tab of their &amp;quot;recent activity&amp;quot; page, whereas the readers can &lt;em&gt;only&lt;/em&gt; tell what the overall tally is. Obviously the author also receives or loses reputation, too. This means the effect on the author and the audience are slightly different.&lt;/p&gt;  &lt;p&gt;For the author, the immediate reward or punishment aspect may sound like the most important aspect: but I&amp;#39;d argue that for many users (particularly those with high reputation) the reputation for a single vote isn&amp;#39;t as important as the effect on the vote tally and what it communicates about your post. There&amp;#39;s usually a positive feedback effect on Stack Overflow: if one answer has a couple of votes and another has none, then the higher voted one is likely to get read more and thus garner more votes. The opposite &lt;em&gt;can&lt;/em&gt; happen: an answer with a negative score will sometimes receive &amp;quot;sympathy&amp;quot; votes from users who think, &amp;quot;This answer isn&amp;#39;t brilliant, but it&amp;#39;s not bad enough to deserve downvotes.&amp;quot;&lt;/p&gt;  &lt;p&gt;For me, the important point about a downvote is that it may indicate I&amp;#39;ve got something wrong in an answer. I may have missed the point of the question in the first place, or simply provided a technically incorrect or unhelpful answer. I want to know about that, so I can fix my answer or delete it if I can&amp;#39;t actually provide any more useful information than is contained in other answers.&lt;/p&gt;  &lt;p&gt;For the reader, the information communicated by the score can be as simple as &amp;quot;this question is interesting/this answer is helpful&amp;quot; vs &amp;quot;this is a poor question/this answer is harmful&amp;quot;. I would hope that non-regular visitors will quickly get the idea that the highest voted answers are &lt;em&gt;likely&lt;/em&gt; to be the best ones, and that answers with a negative score really shouldn&amp;#39;t be trusted. It doesn&amp;#39;t always work that way, but it&amp;#39;s a reasonable rule of thumb.&lt;/p&gt;  &lt;p&gt;So, how do I vote?&lt;/p&gt;  &lt;h3&gt;How I react to questions&lt;/h3&gt;  &lt;p&gt;I generally upvote a question if it&amp;#39;s been well written and I think the problem is sufficiently common that it&amp;#39;s going to help someone else searching for it. I&amp;#39;ll also upvote it if it&amp;#39;s particularly interesting, even if it&amp;#39;s not a very general problem. I suspect I should upvote questions more often - and I also suspect that&amp;#39;s true of many users.&lt;/p&gt;  &lt;p&gt;I very rarely downvote a question, however. If the question is inappropriate, I&amp;#39;ll usually vote to close it. If it&amp;#39;s badly written but intelligible, I&amp;#39;ll edit it. If it isn&amp;#39;t precise enough (just lacks information) I&amp;#39;ll ask for more information in a comment. I don&amp;#39;t see much &lt;em&gt;use&lt;/em&gt; in downvoting. Now there are various users who don&amp;#39;t support the idea of closing a question at all, of course - and if closing weren&amp;#39;t an option &lt;em&gt;then&lt;/em&gt; I would downvote instead. However, I personally support question closing (when appropriate, of course - I&amp;#39;m not saying every closed question deserved it).&lt;/p&gt;  &lt;h3&gt;How I react to answers&lt;/h3&gt;  &lt;p&gt;I will generally upvote an answer if I feel it&amp;#39;s correct and helpful. If there are multiple posts which effectively answer a question, I will usually upvote the best one, but others which provide other bits of relevant information may get a vote too. Again, I probably don&amp;#39;t upvote as often as I should.&lt;/p&gt;  &lt;p&gt;I downvote if I see an answer as &lt;em&gt;actively unhelpful&lt;/em&gt;: this is usually if it&amp;#39;s technically inaccurate, or suggests something which I think is a really bad idea (such as string concatenation in a loop without a small, known limit). I &lt;em&gt;don&amp;#39;t&lt;/em&gt; downvote an answer just for being &amp;quot;not as helpful as it could be&amp;quot; or &amp;quot;not as helpful as another answer&amp;quot;. I believe that behaviour discourages people from contributing in the first place, and an extra answer has relatively little cost associated with it. If it contains &lt;em&gt;no&lt;/em&gt; information which isn&amp;#39;t present in another answer then I&amp;#39;d prefer it to be deleted, but I&amp;#39;d leave that suggestion as a comment rather than a downvote.&lt;/p&gt;  &lt;p&gt;Speaking of comments, I practically &lt;em&gt;always&lt;/em&gt; leave a comment when I downvote. A downvote means I believe something is really &lt;em&gt;wrong&lt;/em&gt; with the answer, and it should be fixed: leaving it as it is makes the world a worse place than if it didn&amp;#39;t exist. A downvote without a comment is fairly pointless - it doesn&amp;#39;t help the poster to fix the answer, because they don&amp;#39;t know what they did wrong in the first place. I find it intensely frustrating when someone downvotes one of my answers without giving any reason: apart from anything else, that downvote could be made on the basis of a mistaken belief, but without that belief being expressed I have no way of correcting it. I always take another look at an answer which has been downvoted, but I&amp;#39;m &lt;em&gt;much&lt;/em&gt; more likely to edit it if I&amp;#39;m given a specific reason.&lt;/p&gt;  &lt;p&gt;Note that the reputation loss due to a downvote is almost insignificant - particularly if it&amp;#39;s early in the day (i.e. before very active users hit the 200 cap) - the idea that I&amp;#39;ve written something unhelpful is &lt;em&gt;far&lt;/em&gt; more disconcerting to me than the loss of a tiny amount of rep.&lt;/p&gt;  &lt;p&gt;I can see why users aren&amp;#39;t prompted for a comment on a downvote - it would be very easy to just type garbage, and that would be worse than no comment at all. It would also require the comment to be anonymised in order to keep the vote itself anonymous. Even so, I&amp;#39;d ask courteous readers to add a comment when you downvote one of my answers: I promise not to &amp;quot;retaliate&amp;quot; with a spate of downvotes, but I&amp;#39;d really like to be able to fix the answer!&lt;/p&gt;  &lt;p&gt;In terms of editing, I will often edit an answer for formatting reasons or to correct a small typo, but I edit answers (from other people) less often than I edit questions.&lt;/p&gt;  &lt;h3&gt;How about you?&lt;/h3&gt;  &lt;p&gt;Enough about me - how do you vote? If you downvote without comments, what effect are you trying to achieve? When would you downvote a question rather than editing it, voting to close or leaving a comment? How do you react to downvotes to your own posts?&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1692775" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/Stack+Overflow/default.aspx">Stack Overflow</category></item><item><title>Go on, ask me anything</title><link>http://msmvps.com/blogs/jon_skeet/archive/2009/03/24/go-on-ask-me-anything.aspx</link><pubDate>Tue, 24 Mar 2009 17:22:32 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1681051</guid><dc:creator>skeet</dc:creator><slash:comments>29</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/jon_skeet/rsscomments.aspx?PostID=1681051</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/jon_skeet/commentapi.aspx?PostID=1681051</wfw:comment><comments>http://msmvps.com/blogs/jon_skeet/archive/2009/03/24/go-on-ask-me-anything.aspx#comments</comments><description>&lt;p&gt;This afternoon, I found a comment which had been trapped in the spam bin for this blog. It was from Andrew Rimmer, in reply to my &lt;a href="http://msmvps.com/blogs/jon_skeet/archive/2009/01/15/stack-overflow-reputation-and-being-a-micro-celebrity.aspx"&gt;&amp;quot;micro-celebrity&amp;quot; post&lt;/a&gt;, pointing me at &lt;a href="http://askjonskeet.com"&gt;http://askjonskeet.com&lt;/a&gt;&lt;/p&gt; &lt;p&gt;The world has officially become extremely silly. The surprising thing is, it&amp;#39;s actually &lt;em&gt;useful&lt;/em&gt; - at least for me. A number of times I&amp;#39;ve wanted to find my old answers to questions, so I can either just refer to them in a new answer or mark the new question as a dupe. You might have thought that a simple search such as&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;exceptions site:stackoverflow.com &amp;quot;jon skeet&amp;quot;&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;would suffice - but that finds what other people have said about exceptions in the same questions that I&amp;#39;ve been active in, and it also picks up any questions which happened to get one of the FinalBuilder adverts when the spider fetched them. The &lt;a href="http://askjonskeet.com/search/?q=exceptions"&gt;equivalent search on AskJonSkeet.com&lt;/a&gt; gets good results.&lt;/p&gt; &lt;p&gt;I&amp;#39;ve no idea how useful it will be for anyone else, but personally I love it. Ego? What ego?&lt;/p&gt; &lt;p&gt;Side note to self, puncturing ego slightly: don&amp;#39;t blog on the tube. It&amp;#39;s way too easy to miss your stop...&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1681051" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/Wacky+Ideas/default.aspx">Wacky Ideas</category><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/Stack+Overflow/default.aspx">Stack Overflow</category></item><item><title>Answering technical questions helpfully</title><link>http://msmvps.com/blogs/jon_skeet/archive/2009/02/17/answering-technical-questions-helpfully.aspx</link><pubDate>Tue, 17 Feb 2009 17:50:11 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1672745</guid><dc:creator>skeet</dc:creator><slash:comments>18</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/jon_skeet/rsscomments.aspx?PostID=1672745</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/jon_skeet/commentapi.aspx?PostID=1672745</wfw:comment><comments>http://msmvps.com/blogs/jon_skeet/archive/2009/02/17/answering-technical-questions-helpfully.aspx#comments</comments><description>&lt;p&gt;I&amp;#39;m unsure of whether this should be a &lt;a href="http://msmvps.com/jon.skeet"&gt;blog post&lt;/a&gt; or an &lt;a href="http://pobox.com/~skeet/csharp"&gt;article&lt;/a&gt;, so I&amp;#39;ll probably make it both. I&amp;#39;ve probably written most of it before in Stack Overflow answers, but as I couldn&amp;#39;t find anything when I was looking earlier (to answer a &lt;a href="http://stackoverflow.com/questions/527962"&gt;question about Stack Overflow answers&lt;/a&gt;) I figured it was time to write something in a medium I had more control over.&lt;/p&gt; &lt;p&gt;This is &lt;em&gt;not&lt;/em&gt; a guide to getting huge amounts of reputation on Stack Overflow. As it happens, following the guidelines here is likely to result in decent rep,&amp;nbsp; but I&amp;#39;m sure there are various somewhat underhand ways of gaining reputation without actually being helpful. In other words, I&amp;#39;m not going to explain how you might game the system, but just share my views on how to work &lt;em&gt;with&lt;/em&gt; the system for the benefit of all involved. A lot of this isn&amp;#39;t specific to Stack Overflow, but some of the advice isn&amp;#39;t applicable to some forums.&lt;/p&gt; &lt;p&gt;Hypocrisy warning: I&amp;#39;m not going to claim I always follow everything in this list. I try, but that&amp;#39;s not the same thing - and quite often time pressures will compromise the quality of an answer. Oh, and don&amp;#39;t read anything into the ordering here. It&amp;#39;s how it happened to come out, that&amp;#39;s all.&lt;/p&gt; &lt;h3&gt;Read the question&lt;/h3&gt; &lt;p&gt;All too often I&amp;#39;ve written what I thought was a &lt;em&gt;great&lt;/em&gt; answer... only to reread the question and find out that it wasn&amp;#39;t going to help the questioner at all.&lt;/p&gt; &lt;p&gt;Now, questions are often written pretty badly, leaving out vital information, being vague about the problem, including lots of &lt;em&gt;irrelevant&lt;/em&gt; code but leaving out the crucial bit which probably contains the bug, etc. It&amp;#39;s at least worth commenting on the question to ask for more information, but just occasionally you can apply psychic debugging to answer the question anyway. If you &lt;em&gt;do&lt;/em&gt; have to make assumptions when writing an answer, state them explicitly. That will not only reduce the possibility of miscommunication, but will also point out the areas which need further clarification.&lt;/p&gt; &lt;h3&gt;Code is king&lt;/h3&gt; &lt;p&gt;I can&amp;#39;t believe I nearly posted this article without mentioning sample code.&lt;/p&gt; &lt;p&gt;Answers with sample code are gold... if the code is appropriate. A few rules of thumb:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Make sure it compiles, assuming it&amp;#39;s meant to. This isn&amp;#39;t always possible - for example, I often post at work from a machine without .NET on it, or on the train from a laptop without Java. If you can&amp;#39;t get a compiler to make sure your code is valid, be extra careful in terms of human inspection.  &lt;li&gt;Snippets are okay, but complete programs rock. If you&amp;#39;re not already comfortable with writing short console apps, practise it. Often you can write a complete app in about 15 lines which doesn&amp;#39;t just give the solution, but shows it working. Imagine the level of confidence that gives to anyone reading your answer. Get rid of anything you don&amp;#39;t need - brevity is really helpful. (In C# for example that usually means getting rid of [STAThread], namespace declarations and unused using directives.)  &lt;li&gt;Take a bit of care over formatting. If possible, try to prevent the code wrapping. That&amp;#39;s not always realistically feasible, but it&amp;#39;s a nice ideal. Make sure the spacing at least looks okay - you may want to use a 2-space indent if your code involves a lot of nesting.  &lt;li&gt;If you skip best practices, add a comment. For example, you might include &lt;code&gt;// Insert error handling here&lt;/code&gt; to indicate that production code really should check the return value etc. This doesn&amp;#39;t include omitting the STAThread attribute and working without a namespace - those are just reasonable assumptions and unlikely to be copied wholesale, whereas the main body of the code may well be. If your code leaks resources, someone&amp;#39;s production code may do so as well...&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;Code without an explanation is rarely useful, however. At least provide a sentence or two to explain what&amp;#39;s going on.&lt;/p&gt; &lt;h3&gt;Answer the question &lt;em&gt;and&lt;/em&gt; highlight side-issues&lt;/h3&gt; &lt;p&gt;Other developers don&amp;#39;t always do things the way we&amp;#39;d like them to. Questions often reflect this, basically asking how to do something which (in our view) shouldn&amp;#39;t be attempted in the first place. It may completely infeasible, or it may just be a really bad idea.&lt;/p&gt; &lt;p&gt;Occasionally, the idea is so awful - and possibly harmful to users, especially when it comes to security questions - that the best response is &lt;em&gt;just&lt;/em&gt; to explain (carefully and politely) why this is a really bad thing to do. Usually, however, it&amp;#39;s better to answer the question&lt;em&gt; &lt;/em&gt;and give details of better alternatives at the same time. Personally I prefer to give these alternatives &lt;em&gt;before&lt;/em&gt; the answer to the question asked, as I suspect it makes it more likely that the questioner will read the advice and take it on board. Don&amp;#39;t forget that the more persuasive you can be, the more likely it is they&amp;#39;ll abandon their original plans. In other words, &amp;quot;Don&amp;#39;t do this!&amp;quot; isn&amp;#39;t nearly as useful as &amp;quot;Don&amp;#39;t do this because...&amp;quot;&lt;/p&gt; &lt;h3&gt;It&amp;#39;s okay to guess, but be honest&lt;/h3&gt; &lt;p&gt;This may be controversial. I&amp;#39;ve certainly been downvoted twice on SO for having the temerity to post an answer without being 100% sure that it&amp;#39;s the right one - and (worse?) for admitting as much.&lt;/p&gt; &lt;p&gt;Sometimes there are questions which are slightly outside your own area of expertise, but they feel an awful lot like a situation you&amp;#39;ve been in before. In this kind of case, you can often write an answer which may well help - and would &lt;em&gt;at least&lt;/em&gt; suggest something for the questioner to investigate a a &lt;em&gt;possible&lt;/em&gt; answer to their problem. Sometimes you may be way off base, which is why it&amp;#39;s worth explaining in your answer that you &lt;em&gt;are&lt;/em&gt; applying a bit of educated guesswork. If another answer is posted by an expert in the topic, it may well be worth the questioner trying their solution first... but at least you&amp;#39;re providing an alternative if they run out of other possibilities.&lt;/p&gt; &lt;p&gt;Now, somewhat contradictory...&lt;/p&gt; &lt;h3&gt;Raise the overall accuracy level&lt;/h3&gt; &lt;p&gt;It should go without saying that a correct answer is more helpful than an incorrect one. There are plenty of entirely inaccurate answers on Stack Overflow - and on newsgroups, and basically every online community-based resource I&amp;#39;ve ever seen. This isn&amp;#39;t surprising, but the best ways to counter it are:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Challenge inaccurate information  &lt;li&gt;Provide accurate information yourself&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;One of the key aspects of this is to provide evidence. If you make an objective statement without any sort of disclaimer about your uncertainty, that &lt;em&gt;should&lt;/em&gt; mean you&amp;#39;ve got good reason to believe you&amp;#39;re correct. That doesn&amp;#39;t necessarily mean you need to provide evidence, but as soon as there&amp;#39;s disagreement, evidence is king. If you want to assert that your code is faster than some other code, write a benchmark (carefully!). If you want to prove that an object &lt;em&gt;can&lt;/em&gt; be collected at a certain point in time, write a test to show it. &lt;a href="http://pobox.com/~skeet/csharp/complete.html"&gt;Short but complete programs&lt;/a&gt; are great for this, and can stop an argument dead in its tracks.&lt;/p&gt; &lt;p&gt;Another source of evidence is documentation and specifications. Be aware that they&amp;#39;re not always accurate, but I generally believe documentation unless I have a specific reason to doubt it.&lt;/p&gt; &lt;h3&gt;Provide links to related resources&lt;/h3&gt; &lt;p&gt;There have been a few questions on Stack Overflow as to whether it&amp;#39;s appropriate to link to other resources on the web. My own opinion is that it&amp;#39;s &lt;em&gt;absolutely&lt;/em&gt; appropriate and can add a lot of value to an answer. In particular, I like to link to:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;MSDN and JavaDoc documentation, or the equivalent for other platforms. With MSDN URLs, if they end in something like http://msdn.microsoft.om/foo(VS80).aspx, take the bit in brackets out of the URL (leaving http://msdn.microsoft.om/foo.aspx in this case). That way the link will always be to the most recent version of the documentation, and it doesn&amp;#39;t give WMD as many problems either.  &lt;li&gt;Language specifications, in particular those for &lt;a href="http://download.microsoft.com/download/3/8/8/388e7205-bc10-4226-b2a8-75351c669b09/CSharp%20Language%20Specification.doc"&gt;C#&lt;/a&gt; and &lt;a href="http://java.sun.com/docs/books/jls/third_edition/html/j3TOC.html"&gt;Java&lt;/a&gt;. I generally link to the Word document for the C# spec, which has the disadvantage that I can&amp;#39;t link to a specific section, and it won&amp;#39;t just open in the browser. On the other hand, I find it easier to navigate than the MSDN version, and I&amp;#39;ve seen inaccuracies in MSDN.  &lt;li&gt;My own articles and blog posts (unsurprisingly :)  &lt;li&gt;Wikipedia  &lt;li&gt;Other resources which are unlikely to become unavailable&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;The point about the resources not becoming unavailable is important - one of the main arguments against linking is that the page might go away in the future. That&amp;#39;s not a particularly compelling argument for most reference material IMO, but it &lt;em&gt;is&lt;/em&gt; relevant in other cases. Either way, it&amp;#39;s worth including some sort of summary of what you&amp;#39;re linking to - a link on its own doesn&amp;#39;t really invite the reader to follow it, whereas a quick description of what they&amp;#39;ll find there provides more incentive.&lt;/p&gt; &lt;p&gt;One quick tip: In Chrome I have an MSDN &amp;quot;search engine&amp;quot; set up and in Firefox a keyword bookmark. In both cases the URL is http://msdn.microsoft.com/en-us/library/%s.aspx - this makes it easier to get to the MSDN page for a particular namespace, type or member. For example, by typing &amp;quot;msdn system.io.fileinfo&amp;quot; I get straight to &lt;a href="http://msdn.microsoft.com/en-us/library/system.io.fileinfo.aspx"&gt;the FileInfo page&lt;/a&gt;. It doesn&amp;#39;t work for generics, however. At some point I&amp;#39;d like to make this simpler somehow...&lt;/p&gt; &lt;h3&gt;Care about your reader: spelling, grammar and style matter&lt;/h3&gt; &lt;p&gt;I&amp;#39;m lucky: I&amp;#39;m a native English speaker, and I have a reasonably good natural command of English. Having said that, I still take a certain amount of care when writing answers: I&amp;#39;ll often rewrite a sentence several times until I feel it works. I&amp;#39;ve noticed that answers with correct spelling and grammar are generally upvoted more than ones with essentially the same content but less careful presentation.&lt;/p&gt; &lt;p&gt;I&amp;#39;m not recommending style &lt;em&gt;over&lt;/em&gt; substance; I&amp;#39;m saying that both are important. You could be putting forward the most insightful comment in the world, but if you can&amp;#39;t communicate it effectively to your readers, it&amp;#39;s not going to help anyone. Having said that...&lt;/p&gt; &lt;h3&gt;A time-limited answer may be better than no answer at all&lt;/h3&gt; &lt;p&gt;I answer Stack Overflow questions in whatever spare time I have: waiting for a build, on the train, taking a break from editing etc. I frequently see a question which would take a good 15 minutes or more to answer properly - but I only have 30 seconds. If the question already has answers, there&amp;#39;s probably no sensible contribution I can make, but if the question is completely unanswered, I sometimes add a very short answer with the most important points I can think of at the time.&lt;/p&gt; &lt;p&gt;Ideally, I&amp;#39;d then go back later and edit the answer to make it more complete - but at least I may have given the questioner something to think about or an option to try. Usually these &amp;quot;quickies&amp;quot; are relatively fruitless, but occasionally I&amp;#39;ll come back to find that the answer was accepted: the slight nudge in the answer was all that was required. If I&amp;#39;m feeling diligent at that point I&amp;#39;ll still complete the answer, but the point is that a brief answer is usually better than nothing.&lt;/p&gt; &lt;h3&gt;Don&amp;#39;t be afraid to delete (or edit heavily) useless answers&lt;/h3&gt; &lt;p&gt;It&amp;#39;s almost inevitable that if you post enough answers, one of them will be less than helpful. It may start off being a good one, but if a later answer includes all the information from your answer and more, or explains it in a better way, it&amp;#39;s just clutter.&lt;/p&gt; &lt;p&gt;Likewise if you make a wild stab in the dark about the cause of a problem, and that guess turns out to be wrong, your answer could become actively unhelpful. Usually the community will let you know this in comments or voting, but sometimes you have to recognise it on your own.&lt;/p&gt; &lt;h3&gt;Be polite&lt;/h3&gt; &lt;p&gt;It&amp;#39;s a shame that I have to include this, and it&amp;#39;s even more of a shame that I need to take better notice of it myself. However boneheaded a question is, there&amp;#39;s no need to be rude. You can express your dismay at a question, and even express dismay at someone failing to read your answer properly, without resorting to inflammatory language. In the end, no-one really wins from a flame war. Remember that there&amp;#39;s a real person at the other end of the network connection, and they&amp;#39;re probably just as frustrated with you as you are with them. If things are getting out of hand, just write a polite note explaining that you don&amp;#39;t think it&amp;#39;s productive to discuss the topic any more, and walk away. (This can be surprisingly difficult advice to heed.)&lt;/p&gt; &lt;p&gt;Next time I get too &amp;quot;involved&amp;quot; in a question, could someone please direct me to this point? And don&amp;#39;t take &amp;quot;But I&amp;#39;m &lt;em&gt;right&lt;/em&gt;, darnit!&amp;quot;&amp;nbsp; as an excuse.&lt;/p&gt; &lt;h3&gt;Don&amp;#39;t &amp;quot;answer and run&amp;quot;&lt;/h3&gt; &lt;p&gt;Sometimes an answer is very, very nearly spot on - but that final 1% is all the difference between the reader understanding fully and having a dangerous misunderstanding of the topic.&lt;/p&gt; &lt;p&gt;Stack Overflow makes it pretty easy to see comments to your answers: monitor this carefully so you can respond and clarify where appropriate. Many web forums have an &amp;quot;email me if this thread is upated&amp;quot; option - again, this is useful. It&amp;#39;s really frustrating (as a questioner) to be left hanging with an answer which looks like it &lt;em&gt;might&lt;/em&gt; solve a real headache, if only you could just get the ear of the author for a moment.&lt;/p&gt; &lt;p&gt;Having said all of this:&lt;/p&gt; &lt;h3&gt;Have fun&lt;/h3&gt; &lt;p&gt;In my experience the most useful users are the ones who are obviously passionate about helping others. Don&amp;#39;t do it out of some misguided sense of &amp;quot;duty&amp;quot; - no-one&amp;#39;s paying you to do this (I assume) and no-one can reasonably complain if you just haven&amp;#39;t got the time or energy to answer their question. Save yourself for a time when you can be more enthusiastic and enjoy what you&amp;#39;re doing. Go ahead, have a cup of coffee and watch a Youtube video or something instead. You don&amp;#39;t &lt;em&gt;have&lt;/em&gt; to check whether there are any new questions!&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1672745" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/General/default.aspx">General</category><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/Stack+Overflow/default.aspx">Stack Overflow</category></item><item><title>Benchmarking: designing an API with unusual goals</title><link>http://msmvps.com/blogs/jon_skeet/archive/2009/02/02/benchmarking-designing-an-api-with-unusual-goals.aspx</link><pubDate>Mon, 02 Feb 2009 20:10:21 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1668242</guid><dc:creator>skeet</dc:creator><slash:comments>8</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/jon_skeet/rsscomments.aspx?PostID=1668242</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/jon_skeet/commentapi.aspx?PostID=1668242</wfw:comment><comments>http://msmvps.com/blogs/jon_skeet/archive/2009/02/02/benchmarking-designing-an-api-with-unusual-goals.aspx#comments</comments><description>&lt;p&gt;In a couple of recent posts I&amp;#39;ve written about a &lt;a href="http://msmvps.com/blogs/jon_skeet/archive/2009/01/26/benchmarking-made-easy.aspx"&gt;benchmarking framework&lt;/a&gt; and the &lt;a href="http://msmvps.com/blogs/jon_skeet/archive/2009/01/29/for-vs-foreach-on-arrays-and-lists.aspx"&gt;results it produced for using for vs foreach in loops&lt;/a&gt;. I&amp;#39;m pleased with what I&amp;#39;ve done so far, but I don&amp;#39;t think I&amp;#39;ve gone far enough yet. In particular, while it&amp;#39;s good at testing multiple algorithms against a single input, it&amp;#39;s not good at trying several different inputs to demonstrate the complexity vs input size. I wanted to rethink the design at three levels - what the framework would be capable of, how developers would use it, and then the fine-grained level of what the API would look like in terms of types, methods etc. These may all sound quite similar on the face of it, but this project is somewhat different to a lot of other coding I&amp;#39;ve done, mostly because I want to lower the barrier to entry as far as humanly possible.&lt;/p&gt;  &lt;p&gt;Before any of this is meaningful, however, I really needed an idea of the fundamental goal. Why was I writing yet another benchmarking framework anyway? While I normally cringe at mission statements because they&amp;#39;re so badly formulated and used, I figured this time it would be helpful.&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;Minibench makes it &lt;strong&gt;easy&lt;/strong&gt; for &lt;strong&gt;developers&lt;/strong&gt; to &lt;strong&gt;write&lt;/strong&gt; and &lt;strong&gt;share&lt;/strong&gt; tests to &lt;strong&gt;investigate&lt;/strong&gt; and &lt;strong&gt;measure&lt;/strong&gt; code &lt;strong&gt;performance&lt;/strong&gt;.&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;The words in bold (or for the semantically inclined, the strong words) are the real meat of it. It&amp;#39;s quite scary that even within a single sentence there are seven key points to address. Some are quite simple, others cause grief. Now let&amp;#39;s look at each of the areas of design in turn.&lt;/p&gt;  &lt;p&gt;Each element of the design should either clearly contribute to the mission statement or help in a non-functional way (e.g. make the project feasible in a reasonable timeframe, avoid legal issues etc). I&amp;#39;m aware that with the length of this post, it sounds like I&amp;#39;m engaging in &amp;quot;big upfront design&amp;quot; but I&amp;#39;d like to think that it&amp;#39;s at least informed by my recent attempt, and that the design criteria here are statements of intent rather than implementation commitments. (Aargh, buzzword bingo... please persevere!)&lt;/p&gt;  &lt;h3&gt;What can it do?&lt;/h3&gt;  &lt;p&gt;As we&amp;#39;ve already said, it&amp;#39;s got to be able to measure code performance. That&amp;#39;s a pretty vague definition, however, so I&amp;#39;m going to restrict it a bit - the design is as much about saying what &lt;em&gt;isn&amp;#39;t&lt;/em&gt; included as what &lt;em&gt;is&lt;/em&gt;.&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Each test will take the form of a single piece of code which is executed many times by the framework. It will have an input and an expected output. (Operations with no natural output can return a constant; I&amp;#39;m not going to make any special allowance for them.) &lt;/li&gt;    &lt;li&gt;The framework should take the tedium out of testing. In particular I don&amp;#39;t want to have to run it several times to get a reasonable number of iterations. I &lt;em&gt;suspect&lt;/em&gt; it won&amp;#39;t be feasible to get the framework to guess appropriate inputs, but that would be lovely if possible. &lt;/li&gt;    &lt;li&gt;Only wall time is measured. There are loads of different metrics which &lt;em&gt;could&lt;/em&gt; be applied: CPU execution time, memory usage, IO usage, lock contention - all kinds of things. Wall time (i.e. actual time elapsed, as measured by a clock on the wall) is by far the simplest to understand and capture, and it&amp;#39;s the one most frequently cited in newsgroup and forum questions in my experience. &lt;/li&gt;    &lt;li&gt;The benchmark is uninstrumented. I&amp;#39;m not going to start rewriting your code dynamically. Frankly this is for reasons of laziness. A really professional benchmarking system might take your IL and wrap it in a timing loop within a single method, somehow enforcing that the result of each iteration is used. I don&amp;#39;t believe that&amp;#39;s worth my time and energy, as well as quite possibly being beyond my capabilities. &lt;/li&gt;    &lt;li&gt;As a result of the previous bullet, the piece of code to be run lots of times needs to be non-trivial. The reality is that it&amp;#39;ll end up being called as a delegate. This is pretty quick, but if you&amp;#39;re just testing &amp;quot;is adding two doubles faster or slower than adding two floats&amp;quot; then you&amp;#39;ll need to put a bit more work in (e.g. having a loop in your own code as well). &lt;/li&gt;    &lt;li&gt;As well as the use case of &amp;quot;which of these algorithms performs the best with this input?&amp;quot; I want to support &amp;quot;how does the performance vary as a function of the input?&amp;quot; This should support multiple algorithms at the same time as multiple inputs. &lt;/li&gt;    &lt;li&gt;The output should be flexible but easy to describe in code. For single-input tests simple text output is fine (although the exact figures to produce can be interesting); for multiple inputs against multiple tests a graph would often be ideal. If I don&amp;#39;t have the energy to write a graphing output I should at least support writing to CSV or TSV so that a spreadsheet or graphing tool can do the heavy lifting. &lt;/li&gt;    &lt;li&gt;The output should be &lt;em&gt;useful&lt;/em&gt; - it should make it easy to compare the performance of different algorithms and/or inputs. It&amp;#39;s clear from the previous post here that &lt;em&gt;just&lt;/em&gt; including the scaled score doesn&amp;#39;t give an obvious meaning. Some careful wording in the output, as well as labeled columns, may be required. This is emphatically &lt;em&gt;not&lt;/em&gt; a dig at anyone confused by the last post - any confusion was my own fault.&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Okay, that doesn&amp;#39;t sound too unreasonable. The next area is much harder, in my view.&lt;/p&gt;  &lt;h3&gt;How does a developer use it?&lt;/h3&gt;  &lt;p&gt;Possibly the most important word in the mission statement is &lt;strong&gt;share&lt;/strong&gt;. The reason I started this project at all is that I was fed up with spending ages writing timing loops for benchmarks which I&amp;#39;d then post on newsgroups or Stack Overflow. That means there are two (overlapping) categories of user:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;A developer writing a test. This needs to be easy, but that&amp;#39;s an aspect of design that I&amp;#39;m reasonably familiar with. I&amp;#39;m not saying I&amp;#39;m &lt;em&gt;good&lt;/em&gt; at it, but at least I have some prior experience. &lt;/li&gt;    &lt;li&gt;A developer reading a newsgroup/forum post, and wanting to run the benchark for themselves. This distribution aspect is the hard bit - or at least the bit requiring imagination. I want the barrier to running the code to be really, &lt;em&gt;really&lt;/em&gt; low. I suspect that there&amp;#39;ll be a &amp;quot;fear of the unknown&amp;quot; to start with which is hard to conquer, but if the framework becomes widely used I want the reader&amp;#39;s reaction to be: &amp;quot;Ah, there&amp;#39;s a MiniBench for this. I&amp;#39;m confident that I can download and run this code with almost no effort.&amp;quot; &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;This second bullet is the one that my friend Douglas and I have been discussing over the weekend, in some ways playing a game of one-upmanship: &amp;quot;I can think of an idea which is &lt;em&gt;even easier&lt;/em&gt; than yours.&amp;quot; It&amp;#39;s a really fun game to play. Things we&amp;#39;ve thought about so far:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;A web page which lets you upload a full program (without the framework) and spits out a URL which can be posted onto Stack Overflow etc. The user would then choose from the following formats: &lt;/li&gt;    &lt;ul&gt;     &lt;li&gt;Single .cs file containing the whole program - just compile and run. (This would also be shown on the download page.) &lt;/li&gt;      &lt;li&gt;Test code only - for those whole already have the framework &lt;/li&gt;      &lt;li&gt;Batch file - just run it to extract/build/run the C# code. &lt;/li&gt;      &lt;li&gt;NAnt project file containing the C# code embedded in it - just run NAnt &lt;/li&gt;      &lt;li&gt;MSBuild project file - ditto but with msbuild. &lt;/li&gt;      &lt;li&gt;Zipped project – open the project to load the test in one file and the framework code in other (possibly separate) .cs files &lt;/li&gt;      &lt;li&gt;Zipped solution – open to load two projects: the test code in one and the framework in the other &lt;/li&gt;   &lt;/ul&gt;    &lt;li&gt;A web page which which lets you upload your results and browse the results of others &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Nothing&amp;#39;s finalised here, but I like the general idea. I&amp;#39;ve managed (fairly easily) to write a &amp;quot;self-building&amp;quot; batch file, but I haven&amp;#39;t tried with NAnt/MSBuild yet. I can&amp;#39;t imagine it&amp;#39;s that hard - but then I&amp;#39;m not sure how much value there is either. What I &lt;em&gt;do&lt;/em&gt; want to try to aim for is users running the tests properly, first time, without much effort. Again, looking back at the last post, I want to make it obvious to users if they&amp;#39;re running under a debugger, which is almost always the wrong thing to be doing. (I&amp;#39;m pretty sure there&amp;#39;s an API for this somewhere, and if there&amp;#39;s not I&amp;#39;m sure I can work out an evil way of detecting it anyway.)&lt;/p&gt;  &lt;p&gt;The main thing is the ease of downloading and running the benchmark. I can&amp;#39;t see how it could be much easier than &amp;quot;follow link; choose format and download; run batch file&amp;quot; - unless the link itself was to the batch file, of course. (That would make it harder to use for people who wanted to get the source in a more normal format, of course.)&lt;/p&gt;  &lt;p&gt;Going back to the point of view of the developer writing the test, I need to make sure it&amp;#39;s easy enough for &lt;em&gt;me&lt;/em&gt; to use from home, work and on the train. That &lt;em&gt;may&lt;/em&gt; mean a web page where I can just type in code, the input and expected output, and let it fill in the rest of the code for me. It &lt;em&gt;may&lt;/em&gt; mean compiling a source file against a library from the command line. It &lt;em&gt;may&lt;/em&gt; mean compiling a source file against the source code of the framework from the command line, with the framework code all in one file. It &lt;em&gt;may&lt;/em&gt; mean building in Visual Studio. I&amp;#39;d like to make all of these cases as simple as possible - which is likely to make it simple for other developers as well. I&amp;#39;m not planning on optimising the experience when it comes to writing a benchmark on my mobile though - that might be a step too far!&lt;/p&gt;  &lt;h3&gt;What should the API look like?&lt;/h3&gt;  &lt;p&gt;When we get down to the nitty-gritty of types and methods, I think what I&amp;#39;ve got is a good starting point. There are still a few things to think about though:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;We &lt;em&gt;nearly&lt;/em&gt; have the functionality required for running a suite with different inputs already - the only problem is that we&amp;#39;re specifying the input (and expected output) in the constructor rather than as parameters to the RunTests method. I could change that... but then we lose the benefit of type inference when creating the suite. I haven&amp;#39;t resolved this to my satisfaction yet :(&lt;/li&gt;    &lt;li&gt;The idea of having the suite automatically set up using attributed methods appeals, although we&amp;#39;d still need a Main method to create the suite and format the output. The suite creation can be simplified, but the chances of magically picking the most appropriate output are fairly slim. I suppose it could go for the &amp;quot;scale to best by number of iterations and show all columns&amp;quot; option by default... that still leaves the input and expected output, of course. I&amp;#39;m sure I&amp;#39;ll have &lt;em&gt;something&lt;/em&gt; like this as an option, but I don&amp;#39;t know how far it will go.&lt;/li&gt;    &lt;li&gt;The &amp;quot;configuration&amp;quot; side of it is expressed as a couple of constants at the moment. These control the minimum amount of time to run tests for before we believe we&amp;#39;ll be able to guess how many iterations we&amp;#39;ll need to get close to the target time, and the target time itself. These are currently set at 2 seconds and 30 seconds respectively - but when running tests just to check that you&amp;#39;ve got the right output format etc, that&amp;#39;s far too long. I suspect I should make a test suite have a configuration, and &lt;em&gt;default&lt;/em&gt; to those constants but allow them to be specified on the command line as well, or explicitly in code.&lt;/li&gt;    &lt;li&gt;Why do we need to set the expected output? In many cases you can be pretty confident that at least &lt;em&gt;one&lt;/em&gt; of the test cases will be correct - so it&amp;#39;s probably simpler just to run each test once and check that the results are the same for all of them, and take that as the expected output. If you don&amp;#39;t have to specify the expected output, it becomes easier to specify a sequence of inputs to test.&lt;/li&gt;    &lt;li&gt;Currently BenchmarkResult is nongeneric. This makes things simpler internally - but should a result know the input that it was derived from? Or should the ResultSuite (which is also nongeneric) know the input that has been applied to all its functions? The information will certainly need to be &lt;em&gt;somewhere&lt;/em&gt; so that it can be output appropriately in the multiple input case.&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;My main points of design focus around three areas:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Is it easy to pick up? The more flexible it is, with lots of options, the more daunting it may seem.&lt;/li&gt;    &lt;li&gt;Is it flexible enough to be useful in a variety of situations? I don&amp;#39;t know what users will want to benchmark - and I don&amp;#39;t build the right tool, it will be worthless to them.&lt;/li&gt;    &lt;li&gt;Is the resulting test code easy and brief enough to include in a forum post, with a link to the full program? Will readers understand it?&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;As you can see, these are aimed at three slightly different people: the first time test writer, the veteran test writer, and the first time test reader. Getting the balance between the three is tricky.&lt;/p&gt;  &lt;h3&gt;What&amp;#39;s next?&lt;/h3&gt;  &lt;p&gt;I haven&amp;#39;t started rewriting the framework yet, but will probably do so soon. This time I hope to do it in a rather more test-driven way, although of course the timing-specific elements will be tricky unless I start using a programmatic clock etc. I&amp;#39;d really like comments around this whole process:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Is this worth doing?&lt;/li&gt;    &lt;li&gt;Am I asking the right questions?&lt;/li&gt;    &lt;li&gt;Are my answers so far headed in the right direction?&lt;/li&gt;    &lt;li&gt;What else haven&amp;#39;t I thought of?&lt;/li&gt; &lt;/ul&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1668242" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/General/default.aspx">General</category><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/Stack+Overflow/default.aspx">Stack Overflow</category><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/Benchmarking/default.aspx">Benchmarking</category></item><item><title>Programming is hard</title><link>http://msmvps.com/blogs/jon_skeet/archive/2009/01/29/programming-is-hard.aspx</link><pubDate>Thu, 29 Jan 2009 20:28:22 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1667051</guid><dc:creator>skeet</dc:creator><slash:comments>22</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/jon_skeet/rsscomments.aspx?PostID=1667051</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/jon_skeet/commentapi.aspx?PostID=1667051</wfw:comment><comments>http://msmvps.com/blogs/jon_skeet/archive/2009/01/29/programming-is-hard.aspx#comments</comments><description>&lt;p&gt;One of the answers to my &amp;quot;controversial opinions&amp;quot; question on Stack Overflow claims that &amp;quot;&lt;a href="http://stackoverflow.com/questions/406760/whats-your-most-controversial-programming-opinion/479007#479007"&gt;programming is so easy a five year old can do it.&lt;/a&gt;&amp;quot;&lt;/p&gt; &lt;p&gt;I&amp;#39;m sure there are some aspects of programming which a five year old can do. Other parts are apparently very hard though. Today I came to the following conclusion:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;If your code deals with arbitrary human text, it&amp;#39;s probably broken. (Have you taken the &lt;a href="http://www.moserware.com/2008/02/does-your-code-pass-turkey-test.html"&gt;Turkey test&lt;/a&gt; recently?)  &lt;li&gt;If your code deals with floating point numbers, it&amp;#39;s probably broken.  &lt;li&gt;If your code deals with concurrency (whether that means database transactions, threading, whatever), it&amp;#39;s probably broken.  &lt;li&gt;If your code deals with dates, times and time zones, it&amp;#39;s probably broken. (Time zones in particular are hideous.) &lt;li&gt;If your code has a user interface with anything other than a fixed size and a fixed set of labels (no i18n), it&amp;#39;s probably broken.&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;You know what I like working with? Integers. They&amp;#39;re nice and predictable. Give me integers, and I can pretty much predict how they&amp;#39;ll behave. So long as they don&amp;#39;t overflow. Of have an architecture-and-processor-dependent size.&lt;/p&gt; &lt;p&gt;Maybe you think I&amp;#39;m too cynical. I think I&amp;#39;m rather bullish, actually. After all, I used the word &amp;quot;probably&amp;quot; on all of those bullet points.&lt;/p&gt; &lt;p&gt;The thing that amazes me is that despite all this hardness, despite us never really achieving perfection, programs seem to work well enough most of the time. It&amp;#39;s a bit like a bicycle - it really shouldn&amp;#39;t work. I mean, if you&amp;#39;d never seen one working, and someone told you that:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;You can&amp;#39;t really balance when it&amp;#39;s stationary. You have to go at a reasonable speed to stay stable.&lt;/li&gt; &lt;li&gt;Turning is a lot easier if you lean towards the ground.&lt;/li&gt; &lt;li&gt;The bit of the bike which is actually in contact with the ground is always stationary, even when the bike itself is moving.&lt;/li&gt; &lt;li&gt;You stop by squeezing bits of rubber onto the wheels.&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;Would you not be a touch skeptical? Likewise when I see the complexity of software and our collective failure to cope with it, I&amp;#39;m frankly astonished that I can even write this blog post.&lt;/p&gt; &lt;p&gt;It&amp;#39;s been a hard day. I achieved a small victory over one of the bullet points in the first list today. It took hours, and I pity my colleague who&amp;#39;s going to code review it (I&amp;#39;ve made it as clear as I can, but some things are just designed to mess with your head) - but it&amp;#39;s done. I feel simultaneously satisfied in a useful day&amp;#39;s work, and depressed at the need for it.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1667051" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/General/default.aspx">General</category><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/Stack+Overflow/default.aspx">Stack Overflow</category></item><item><title>Quick rant: why isn't there an Exception(string, params object[]) constructor?</title><link>http://msmvps.com/blogs/jon_skeet/archive/2009/01/23/quick-rant-why-isn-t-there-an-exception-string-params-object-constructor.aspx</link><pubDate>Fri, 23 Jan 2009 21:42:52 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1665160</guid><dc:creator>skeet</dc:creator><slash:comments>26</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/jon_skeet/rsscomments.aspx?PostID=1665160</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/jon_skeet/commentapi.aspx?PostID=1665160</wfw:comment><comments>http://msmvps.com/blogs/jon_skeet/archive/2009/01/23/quick-rant-why-isn-t-there-an-exception-string-params-object-constructor.aspx#comments</comments><description>&lt;p&gt;This &lt;a href="http://stackoverflow.com/questions/474564"&gt;Stack Overflow question&lt;/a&gt; has reminded me of something I often wish existed in common exception constructors - an overload taking a format string and values. For instance, it would be really nice to be able to write:&lt;/p&gt; &lt;div class="code"&gt;&lt;span class="Statement"&gt;throw&lt;/span&gt;&amp;nbsp;&lt;span class="Keyword"&gt;new&lt;/span&gt; IOException(&lt;span class="String"&gt;&amp;quot;Expected to read {0} bytes but only {1} were available&amp;quot;&lt;/span&gt;,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; requiredSize, bytesRead); &lt;/div&gt; &lt;p&gt;Of course, with no way of explicitly inheriting constructors (which I almost always want for exceptions, and almost never want for anything else) it would mean yet another overload to copy and paste from another exception, but the times when I&amp;#39;ve actually written it in my own exceptions it&amp;#39;s been &lt;em&gt;hugely&lt;/em&gt; handy, particularly for tricky cases where you&amp;#39;ve got a lot of data to include in the message. (You&amp;#39;d also want an overload taking a nested exception first as well, adding to the baggage...)&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1665160" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/General/default.aspx">General</category><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/Wacky+Ideas/default.aspx">Wacky Ideas</category><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/Stack+Overflow/default.aspx">Stack Overflow</category></item><item><title>Stack Overflow reputation and being a micro-celebrity</title><link>http://msmvps.com/blogs/jon_skeet/archive/2009/01/15/stack-overflow-reputation-and-being-a-micro-celebrity.aspx</link><pubDate>Thu, 15 Jan 2009 22:39:18 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1662339</guid><dc:creator>skeet</dc:creator><slash:comments>44</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/jon_skeet/rsscomments.aspx?PostID=1662339</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/jon_skeet/commentapi.aspx?PostID=1662339</wfw:comment><comments>http://msmvps.com/blogs/jon_skeet/archive/2009/01/15/stack-overflow-reputation-and-being-a-micro-celebrity.aspx#comments</comments><description>&lt;p&gt;I&amp;#39;ve considered writing a bit about this before, but not done so for fear of looking like a jerk. I still think I may well end up looking like a jerk, but this is all stuff I&amp;#39;m interested in and I&amp;#39;ll enjoy writing about it, so on we go. Much of this is based on experiences at and around &lt;a href="http://pobox.com/~skeet/csharp"&gt;Stack Overflow&lt;/a&gt;, and it&amp;#39;s more likely to be interesting to you if you&amp;#39;re a regular there or at least know the basic premises and mechanics. Even then you may well not be particularly interested - as much as anything, this post is to try to get some thoughts out of my system so I can stop thinking about how I &lt;em&gt;would&lt;/em&gt; blog about it. If you don&amp;#39;t want the introspection, but want to know how to judge my egotism, skipping to the summary is probably a good plan. If you really don&amp;#39;t care at all, that&amp;#39;s probably a healthy sign. Quit now while you&amp;#39;re ahead.&lt;/p&gt; &lt;h3&gt;What is a micro-celebrity?&lt;/h3&gt; &lt;p&gt;A couple of minutes ago, I thought I might have been original with the term &amp;quot;micro-celebrity&amp;quot; but &lt;a href="http://www.google.co.uk/search?q=micro-celebrity"&gt;I&amp;#39;m clearly not&lt;/a&gt;. I may well not use the term the same way other people do, however, so here&amp;#39;s my rough definition solely for the purposes of this post:&lt;/p&gt; &lt;blockquote&gt;A micro-celebrity is someone who gains a significant level of notoriety within a relatively limited community on the internet, usually with a positive feedback loop.&lt;/blockquote&gt; &lt;p&gt;Yes, it&amp;#39;s woolly. Not to worry.&lt;/p&gt; &lt;p&gt;I would consider myself to have been a micro-celebrity in five distinct communities over the course of the last 14 years:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;The alt.books.stephen-king newsgroup&lt;/li&gt; &lt;li&gt;The mostly web-based community around Team17&amp;#39;s series of &amp;quot;Worms&amp;quot; games (well, the first few, on the PC only)&lt;/li&gt; &lt;li&gt;The comp.lang.java.* newsgroups&lt;/li&gt; &lt;li&gt;The microsoft.public.dotnet.languages.csharp newsgroup&lt;/li&gt; &lt;li&gt;Stack Overflow&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;The last has been far and away the most blatant case. This is roughly how it goes - or at least how it&amp;#39;s gone in each of the above cases:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Spend some time in the community, post quite a lot. Shouting loudly works remarkably well on the internet - if you&amp;#39;re among the most prolific writers in a group, you &lt;em&gt;will&lt;/em&gt; get noticed. Admittedly it helps to try hard to post well-written and interesting thoughts.&lt;/li&gt; &lt;li&gt;After a while, a few people will refer to you in their other conversations. For instance, if someone in the Java newsgroup was talking about &amp;quot;objects being passed by reference&amp;quot;, another poster might say something like &amp;quot;Don&amp;#39;t let Jon Skeet hear you talking like that.&amp;quot;&lt;/li&gt; &lt;li&gt;Play along with it, just a bit. Don&amp;#39;t blow your own trumpet, but equally don&amp;#39;t discourage it. A few wry comments to show that you don&amp;#39;t mind often go down well.&lt;/li&gt; &lt;li&gt;Sooner or later, you will find yourself not just mentioned in another topic, but being the topic of conversation yourself. At this point, it&amp;#39;s no longer an inside joke that just the core members of the group &amp;quot;get&amp;quot; - you&amp;#39;re now communal property, and almost &lt;em&gt;any&lt;/em&gt; regular will be part of the joke.&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;One interesting thing you might have noticed about the above is that it doesn&amp;#39;t really take very much skill. It takes a fair amount of time, and ideally you should have some reasonable thoughts and the ability to express yourself clearly, but you certainly don&amp;#39;t have to be a genius. Good job, really.&lt;/p&gt; &lt;h3&gt;How much do you care?&lt;/h3&gt; &lt;p&gt;This is obviously very personal, and I&amp;#39;m only speaking for myself (as ever).&lt;/p&gt; &lt;p&gt;It&amp;#39;s undeniably an ego boost. Just about every day there&amp;#39;s &lt;em&gt;something&lt;/em&gt; on Stack Overflow to laugh about in reference to me. How could I &lt;em&gt;not&lt;/em&gt; enjoy that? How could it not inflate my sense of self-worth just a little bit? I could dismiss it as being entirely silly and meaningless - which it is, ultimately - but it&amp;#39;s still &lt;em&gt;fun&lt;/em&gt; and I get a kick out of it. And yes, I&amp;#39;m sorry to say I bore/annoy my colleagues and wife with the latest Stack Overflow news, because I&amp;#39;ve always been the selfish kind of person who wants to talk about what &lt;em&gt;they&amp;#39;re&lt;/em&gt; up to instead of asking the other person about their interests. This is an unfortunate trait which has relatively little to do with the micro-celebrity business.&lt;/p&gt; &lt;p&gt;One very good thing for keeping my ego in check is that at Google, I converse with people who are smarter than me every day, whether at coffee, breakfast, lunch or just while coding. There&amp;#39;s no sense of anyone trying to make anyone else feel small, but it&amp;#39;s pretty obvious that I&amp;#39;m nothing special when it comes to Google. Now, I don&amp;#39;t want to put on too much false modesty - I know I have a reasonable amount of experience, and I happen to know two very popular platforms reasonably well (which really helps on Stack Overflow- being the world&amp;#39;s greatest guru on MUMPS isn&amp;#39;t going to get you much love), and perhaps most importantly I can communicate pretty well. All of these are good things, and I&amp;#39;m proud of my career and particularly C# in Depth...&lt;/p&gt; &lt;p&gt;... but let&amp;#39;s get real here. The &lt;a href="http://stackoverflow.com/questions/305223/jon-skeet-facts"&gt;Jon Skeet Facts&lt;/a&gt; page isn&amp;#39;t really about me. It&amp;#39;s about making geek jokes where the exact subject is largely irrelevant. It could very easily have been about someone else with little change in the humour. Admittedly the funniest answers (to my mind) are the ones which &lt;em&gt;do&lt;/em&gt; have some bearing on me (particularly the one about having written a book on C# 5.0 already) - but that doesn&amp;#39;t mean there&amp;#39;s anything really serious in it. I hope it&amp;#39;s pretty obvious to everyone that I&amp;#39;m &lt;em&gt;not&lt;/em&gt; a genius programmer. I&amp;#39;d like to think I&amp;#39;m pretty good, but I&amp;#39;m not off-the-charts awesome by any means. (In terms of computer science, I&amp;#39;m nothing special &lt;em&gt;at all&lt;/em&gt; and I have a really limited range of languages/paradigms. I&amp;#39;m trying to do something about those, but it&amp;#39;s hard when there&amp;#39;s always another question to answer.)&lt;/p&gt; &lt;p&gt;It&amp;#39;s worth bearing in mind the &amp;quot;micro&amp;quot; part of micro-celebrity. I suspect that if we somehow got all the C# developers in the world together and asked them whether they&amp;#39;d heard of Jon Skeet, fewer than 0.1% would say yes. (That&amp;#39;s a &lt;em&gt;complete&lt;/em&gt; guess, by the way. I have really no idea. The point is I&amp;#39;m pretty sure it&amp;#39;s a small number.) Compared with the sea of developers, the set of Stack Overflow &lt;em&gt;regulars&lt;/em&gt; is a very small pond.&lt;/p&gt; &lt;p&gt;What I care far more about than praise and fandom is the idea of actually &lt;em&gt;helping&lt;/em&gt; people and making a difference. A couple of days ago I had an email from someone saying that C# in Depth had helped them in an interview: they were able to write more elegant code because now they grok lambda expressions. How cool is that? Yes, I know it&amp;#39;s all slightly sickening in a &lt;a href="http://uk.youtube.com/watch?v=JAIWTLal9e4"&gt;&amp;quot;you do a lot of good work for charity&amp;quot;&lt;/a&gt; kind of way - but I suspect it&amp;#39;s what drives most Stack Overflow regulars. Which leads me on to reputation...&lt;/p&gt; &lt;h3&gt;What does Stack Overflow reputation mean to you?&lt;/h3&gt; &lt;p&gt;In virtually every discussion about the Stack Overflow reputation system and its caps, I try to drop in the question of &amp;quot;what&amp;#39;s the point of reputation? What does it mean to you?&amp;quot; It&amp;#39;s one of those questions which everyone needs to answer for themselves. Jeff Atwood&amp;#39;s answer is that reputation is &lt;a href="http://stackoverflow.com/faq"&gt;how much the system trusts you&lt;/a&gt;. My own answers:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;It&amp;#39;s a daily goal. Making sure I always get to 200 is a fun little task, and then trying to get accepted answers is a challenge.&lt;/li&gt; &lt;li&gt;It&amp;#39;s measurable data, and you can play with graphs and stats. Hey we&amp;#39;re geeks - it&amp;#39;s fun to play with numbers, however irrelevant they are.&lt;/li&gt; &lt;li&gt;It&amp;#39;s an indication of helpfulness &lt;em&gt;to some extent&lt;/em&gt;. It plays to my ego in terms of both pride of knowledge and the fulfillment of helping people.&lt;/li&gt; &lt;li&gt;It&amp;#39;s useful as an indicator of community trust for the system to use, which is probably more important to Jeff than it is to me.&lt;/li&gt; &lt;li&gt;&lt;em&gt;It&amp;#39;s a game&lt;/em&gt;. This is the most important aspect. I love games. I&amp;#39;m &lt;em&gt;fiercely&lt;/em&gt; competitive, and will always try to work out all the corners of a game&amp;#39;s system - things like it being actually somewhat useless getting accepted answers before you&amp;#39;ve reached the 200 limit. I don&amp;#39;t necessarily &lt;em&gt;play&lt;/em&gt; to the corners of the game (I would rather post a useful but unpopular answer than a popular but harmful one, for serious questions) but I enjoy working them out. I would be interested to measure my levels of testosterone when typing furiously away at an answer, hoping to craft something useful before anyone else does. I&amp;#39;m never going to be &amp;quot;macho&amp;quot; physically, but I can certainly be an alpha geek. So long as it doesn&amp;#39;t go too far, I think it&amp;#39;s a positive thing.&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;I sometimes sense (perhaps inaccurately) that Jeff and Joel are frustrated with people getting too hung up about reputation. It&amp;#39;s really unimportant in the grand scheme of things - rep in itself isn&amp;#39;t as much of a net contribution to the world&amp;#39;s happiness as the way that Stack Overflow connects people with questions to people with relevant answers really, really quickly. But rep is one of the things that makes Stack Overflow so &amp;quot;sticky&amp;quot; as a website. It&amp;#39;s not that I wouldn&amp;#39;t answer questions if the reputation system went down - after all, I&amp;#39;ve been answering questions on newsgroups for years, for the other reasons mentioned - but the reputation system certainly &lt;em&gt;helps&lt;/em&gt;. Yes, it&amp;#39;s probably taking advantage of a competitive streak which is in some ways ugly... but the &lt;em&gt;result&lt;/em&gt; is a good one.&lt;/p&gt; &lt;p&gt;One downside of the whole micro-celebrity thing - and in particular of being the top rep earner - is that various suggestions (such as &lt;a href="http://stackoverflow.uservoice.com/pages/general/suggestions/35824-change-the-reputation-limit-algorithm"&gt;changing the rep limit algorithm&lt;/a&gt; and &lt;a href="http://stackoverflow.uservoice.com/pages/general/suggestions/95721-monthly-league-for-reputation"&gt;introducing a monthly league&lt;/a&gt;) make me look really selfish. It&amp;#39;s undeniable that both of the suggestions work in my favour. I happen to believe that both work in the community&amp;#39;s favour too, but I can certainly see why people might get the wrong idea about my motivation. I don&amp;#39;t remember thinking of any suggestions which would work &lt;em&gt;against&lt;/em&gt; my personal interests but in the interests of the community. If I do, I&amp;#39;m pretty sure I&amp;#39;ll post them with no hesitation.&lt;/p&gt; &lt;h3&gt;Summary&lt;/h3&gt; &lt;p&gt;Yes, I like the attention of being a micro-celebrity. It would be ridiculous to deny it, and I don&amp;#39;t think it says much more about me than the fact that I&amp;#39;m human.&lt;/p&gt; &lt;p&gt;Yes, I like competing for reputation, even though it&amp;#39;s blatantly obvious that the figure doesn&amp;#39;t reflect programming prowess. It&amp;#39;s &lt;em&gt;part&lt;/em&gt; of the fuel for my addiction to Stack Overflow.&lt;/p&gt; &lt;p&gt;With this out of the way, I hope to return to more technical blog posts. If anything interesting comes up in the comments, I&amp;#39;ll probably edit this post rather than writing a new one.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1662339" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/General/default.aspx">General</category><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/Stack+Overflow/default.aspx">Stack Overflow</category></item><item><title>Stack Overflow Reputation Tool now online</title><link>http://msmvps.com/blogs/jon_skeet/archive/2009/01/15/stack-overflow-reputation-tool-now-online.aspx</link><pubDate>Thu, 15 Jan 2009 20:12:30 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1662292</guid><dc:creator>skeet</dc:creator><slash:comments>7</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/jon_skeet/rsscomments.aspx?PostID=1662292</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/jon_skeet/commentapi.aspx?PostID=1662292</wfw:comment><comments>http://msmvps.com/blogs/jon_skeet/archive/2009/01/15/stack-overflow-reputation-tool-now-online.aspx#comments</comments><description>&lt;h3&gt;Update:&lt;/h3&gt; &lt;p&gt;Now that the &amp;quot;recent activity&amp;quot; page is working, the feed that the tool was using has been removed. However, the new page offers pretty much everything that the tool did, and a lot more besides. I&amp;#39;ve updated the tool to just redirect to the relevant page, so your bookmarks should still work.&lt;/p&gt; &lt;h3&gt;Original post:&lt;/h3&gt; &lt;p&gt;&lt;a href="http://csharpindepth.com/StackOverflow/ReputationTracker.aspx"&gt;This&lt;/a&gt; is the micro-web-app that my &lt;a href="http://stackoverflow.com/questions/431296/how-can-i-take-more-control-in-asp-net"&gt;recent ASP.NET question&lt;/a&gt; was about. It&amp;#39;s very simple - it shows you the reputation gained or lost by a specified user (typically you) for either today or yesterday. Note that these are Stack Overflow &amp;quot;today&amp;quot; and &amp;quot;yesterday&amp;quot; - i.e. they&amp;#39;re in UTC. That happens to be convenient for me as I&amp;#39;m in the UK, but more importantly it&amp;#39;s in tune with the reputation limits. It does mean that if you&amp;#39;re in a different time zone you&amp;#39;ll see the date changing at potentially unexpected times.&lt;/p&gt; &lt;p&gt;There&amp;#39;s an option for including a record of questions/answers which have received an upvote during the day but which haven&amp;#39;t generated any reputation - this happens if you&amp;#39;ve already hit the reputation limit for the day before the vote.&lt;/p&gt; &lt;p&gt;The worst part about the user interface (to my mind) is that you have to know the ID of the user whose reputation you want to check. This isn&amp;#39;t exactly hard, but it&amp;#39;s slightly annoying. Basically you need to go to the user&amp;#39;s profile page on Stack Overflow and look at the URL. It will be of the form http://stackoverflow.com/users/[user-id]/[user-name] - take the user ID from that, and put it into the tool. I may be able to have a browsing mode just like that on SO at some point, but it will take at least &lt;em&gt;some&lt;/em&gt; work. I&amp;#39;ve been concentrating on the data retrieved rather than the presentation, as you&amp;#39;ll no doubt be able to tell at a glance :)&lt;/p&gt; &lt;p&gt;All the options are specified on the URL, so you can bookmark your own user results very easily. For example:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;My reputation for today: &lt;a href="http://csharpindepth.com/StackOverflow/ReputationTracker.aspx?user=22656&amp;amp;mode=today"&gt;http://csharpindepth.com/StackOverflow/ReputationTracker.aspx?user=22656&amp;amp;mode=today&lt;/a&gt;  &lt;li&gt;My reputation for yesterday, including non-scoring items: &lt;a href="http://csharpindepth.com/StackOverflow/ReputationTracker.aspx?user=22656&amp;amp;mode=yesterday&amp;amp;showzero=true"&gt;http://csharpindepth.com/StackOverflow/ReputationTracker.aspx?user=22656&amp;amp;mode=yesterday&amp;amp;showzero=true&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;(If anyone has any better ideas for the URL parameter than &amp;quot;showzero&amp;quot; I&amp;#39;m very much open to suggestions. I can keep backward compatibility for the sake of bookmarks really easily.)&lt;/p&gt; &lt;p&gt;At the moment it&amp;#39;s showing pretty much all the information it receives. I&amp;#39;m hoping that I may be able to work with the Stack Overflow team to make it easy (and importantly, cheap for the SO server) to show a whole date range (e.g. &amp;quot;what happened in the last week?&amp;quot;) and also give details of the number of votes up and down, and when an answer is accepted (or unaccepted).&lt;/p&gt; &lt;p&gt;Enjoy, and share with friends. Feedback welcome. Many thanks to Geoff Dalgas for working with me to limit the impact on the server.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1662292" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/Stack+Overflow/default.aspx">Stack Overflow</category></item><item><title>New addiction: Stack Overflow</title><link>http://msmvps.com/blogs/jon_skeet/archive/2008/09/28/new-addiction-stack-overflow.aspx</link><pubDate>Sun, 28 Sep 2008 07:23:08 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1649078</guid><dc:creator>skeet</dc:creator><slash:comments>3</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/jon_skeet/rsscomments.aspx?PostID=1649078</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/jon_skeet/commentapi.aspx?PostID=1649078</wfw:comment><comments>http://msmvps.com/blogs/jon_skeet/archive/2008/09/28/new-addiction-stack-overflow.aspx#comments</comments><description>&lt;p&gt;This may be old news to many readers, but there&amp;#39;s a relatively new development Q&amp;amp;A site called &lt;a href="http://stackoverflow.com"&gt;Stack Overflow&lt;/a&gt;. I&amp;#39;m not generally a fan of web forums as opposed to newsgroups, but Stack Overflow &lt;em&gt;just works&lt;/em&gt;. In particular, the post/answer editor is better than anything similar that I&amp;#39;ve seen. I&amp;#39;ll readily admit that the reputation side of things appeals to my ego - which and I suspect it&amp;#39;s one of the main reasons it&amp;#39;s so popular. Developers tend to be somewhat egotistical :)&lt;/p&gt; &lt;p&gt;One of the aims of the site is to end up as the pseudo-canonical resource for development questions: sort of a development Wikipedia. Only time will tell whether or not that will actually happen. In particular the fact that early answers are more likely to be read (and voted on) than later ones which have perhaps taken a lot of research and cover the topic more thoroughly. It&amp;#39;s still in public beta, so there&amp;#39;s lots of room for tweaking (and even after launch things could still change, of course).&lt;/p&gt; &lt;p&gt;Just another site to suck up my time...&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1649078" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/General/default.aspx">General</category><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/Stack+Overflow/default.aspx">Stack Overflow</category></item></channel></rss>