<?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 : Wacky Ideas</title><link>http://msmvps.com/blogs/jon_skeet/archive/tags/Wacky+Ideas/default.aspx</link><description>Tags: Wacky Ideas</description><dc:language>en</dc:language><generator>CommunityServer 2008.5 SP2 (Build: 40407.4157)</generator><item><title>Contract classes and nested types within interfaces</title><link>http://msmvps.com/blogs/jon_skeet/archive/2009/10/31/contract-classes-and-nested-types-within-interfaces.aspx</link><pubDate>Sat, 31 Oct 2009 22:04:54 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1736652</guid><dc:creator>skeet</dc:creator><slash:comments>9</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/jon_skeet/rsscomments.aspx?PostID=1736652</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/jon_skeet/commentapi.aspx?PostID=1736652</wfw:comment><comments>http://msmvps.com/blogs/jon_skeet/archive/2009/10/31/contract-classes-and-nested-types-within-interfaces.aspx#comments</comments><description>&lt;p&gt;I&amp;#39;ve just been going through some feedback for the draft copy of the second edition of C# in Depth. In the contracts section, I have an example like this:&lt;/p&gt;  &lt;div class="code"&gt;[ContractClass(&lt;span class="Keyword"&gt;typeof&lt;/span&gt;(ICaseConverterContracts))]     &lt;br /&gt;&lt;span class="Modifier"&gt;public&lt;/span&gt;&amp;#160;&lt;span class="ReferenceType"&gt;interface&lt;/span&gt; ICaseConverter     &lt;br /&gt;{     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="ReferenceType"&gt;string&lt;/span&gt; Convert(&lt;span class="ReferenceType"&gt;string&lt;/span&gt; text);     &lt;br /&gt;}     &lt;br /&gt;    &lt;br /&gt;[ContractClassFor(&lt;span class="Keyword"&gt;typeof&lt;/span&gt;(ICaseConverter))]     &lt;br /&gt;&lt;span class="Modifier"&gt;internal&lt;/span&gt;&amp;#160;&lt;span class="ReferenceType"&gt;class&lt;/span&gt; ICaseConverterContracts : ICaseConverter     &lt;br /&gt;{     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="ReferenceType"&gt;string&lt;/span&gt; ICaseConverter.Convert(&lt;span class="ReferenceType"&gt;string&lt;/span&gt; text)     &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; Contract.Requires(text != &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; Contract.Ensures(Contract.Result&amp;lt;&lt;span class="ReferenceType"&gt;string&lt;/span&gt;&amp;gt;() != &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;span class="Statement"&gt;return&lt;/span&gt;&amp;#160;&lt;span class="Modifier"&gt;default&lt;/span&gt;(&lt;span class="ReferenceType"&gt;string&lt;/span&gt;);     &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; ICaseConverterContracts() {}     &lt;br /&gt;}     &lt;br /&gt;    &lt;br /&gt;&lt;span class="Modifier"&gt;public&lt;/span&gt;&amp;#160;&lt;span class="ReferenceType"&gt;class&lt;/span&gt; InvariantUpperCaseFormatter : ICaseConverter     &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="ReferenceType"&gt;string&lt;/span&gt; Convert(&lt;span class="ReferenceType"&gt;string&lt;/span&gt; text)&amp;#160; &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;return&lt;/span&gt; text.ToUpperInvariant();     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }     &lt;br /&gt;} &lt;/div&gt;  &lt;p&gt;The point is to demonstrate how contracts can be specified for interfaces, and then applied automatically to implementations. In this case, &lt;code&gt;ICaseConverter&lt;/code&gt; is the interface, &lt;code&gt;ICaseConverterContracts&lt;/code&gt; is the &lt;i&gt;contract class&lt;/i&gt; which specifies the contract for the interface, and &lt;code&gt;InvariantUpperCaseFormatter&lt;/code&gt; is the real implementation. The binary rewriter effectively copies the contract into each implementation, so you don&amp;#39;t need to duplicate the contract in the source code.&lt;/p&gt;  &lt;p&gt;The reader feedback asked where the contract class code should live - should it go in the same file as the interface itself, or in a separate file as normal? Now normally, I&amp;#39;m firmly of the &amp;quot;one top-level type per file&amp;quot; persuasion, but in this case I think it makes sense to keep the contract class with the interface. It has no meaning without reference to the interface, after all - it&amp;#39;s not a real implementation to be used in the normal way. It&amp;#39;s essentially metadata. This does, however, leave me feeling a little bit dirty. What I&amp;#39;d &lt;em&gt;really&lt;/em&gt; like to be able to do is nest the contract class inside the interface, just like I do with other classes which are tightly coupled to an &amp;quot;owner&amp;quot; type. Then the code would look like this:&lt;/p&gt;  &lt;div class="code"&gt;[ContractClass(&lt;span class="Keyword"&gt;typeof&lt;/span&gt;(ICaseConverterContracts))]     &lt;br /&gt;&lt;span class="Modifier"&gt;public&lt;/span&gt;&amp;#160;&lt;span class="ReferenceType"&gt;interface&lt;/span&gt; ICaseConverter     &lt;br /&gt;{     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="ReferenceType"&gt;string&lt;/span&gt; Convert(&lt;span class="ReferenceType"&gt;string&lt;/span&gt; text);     &lt;br /&gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; [ContractClassFor(&lt;span class="Keyword"&gt;typeof&lt;/span&gt;(ICaseConverter))]     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Modifier"&gt;internal&lt;/span&gt;&amp;#160;&lt;span class="ReferenceType"&gt;class&lt;/span&gt; ICaseConverterContracts : ICaseConverter     &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;string&lt;/span&gt; ICaseConverter.Convert(&lt;span class="ReferenceType"&gt;string&lt;/span&gt; text)     &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; Contract.Requires(text != &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;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Contract.Ensures(Contract.Result&amp;lt;&lt;span class="ReferenceType"&gt;string&lt;/span&gt;&amp;gt;() != &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;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Statement"&gt;return&lt;/span&gt;&amp;#160;&lt;span class="Modifier"&gt;default&lt;/span&gt;(&lt;span class="ReferenceType"&gt;string&lt;/span&gt;);     &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;private&lt;/span&gt; ICaseConverterContracts() {}     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }     &lt;br /&gt;}     &lt;br /&gt;    &lt;br /&gt;&lt;span class="Modifier"&gt;public&lt;/span&gt;&amp;#160;&lt;span class="ReferenceType"&gt;class&lt;/span&gt; InvariantUpperCaseFormatter : ICaseConverter     &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="ReferenceType"&gt;string&lt;/span&gt; Convert(&lt;span class="ReferenceType"&gt;string&lt;/span&gt; text)&amp;#160; &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;return&lt;/span&gt; text.ToUpperInvariant();     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }     &lt;br /&gt;} &lt;/div&gt;  &lt;p&gt;That would make me feel happier - all the information to do with the interface would be specified within the interface type&amp;#39;s code. It&amp;#39;s possible that with that as a convention, the Code Contracts tooling could cope without the attributes - if interface &lt;code&gt;IFoo&lt;/code&gt; contains a nested class &lt;code&gt;IFooContracts&lt;/code&gt; which implements &lt;code&gt;IFoo&lt;/code&gt;, assume it&amp;#39;s a contract class and handle it appropriately. That would be sweet.&lt;/p&gt;  &lt;p&gt;You know the really galling thing? I&amp;#39;m pretty sure VB &lt;em&gt;does&lt;/em&gt; allow nested types in interfaces...&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1736652" 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></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>An object lesson in blogging and accuracy; was: Efficient "vote counting" with LINQ to Objects - and the value of nothing</title><link>http://msmvps.com/blogs/jon_skeet/archive/2009/09/20/efficient-quot-vote-counting-quot-with-linq-to-objects-and-the-value-of-nothing.aspx</link><pubDate>Sun, 20 Sep 2009 20:48:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1725262</guid><dc:creator>skeet</dc:creator><slash:comments>11</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/jon_skeet/rsscomments.aspx?PostID=1725262</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/jon_skeet/commentapi.aspx?PostID=1725262</wfw:comment><comments>http://msmvps.com/blogs/jon_skeet/archive/2009/09/20/efficient-quot-vote-counting-quot-with-linq-to-objects-and-the-value-of-nothing.aspx#comments</comments><description>&lt;p&gt;Well, this is embarrassing.&lt;/p&gt;  &lt;p&gt;Yesterday evening, I excitedly wrote a blog post about an interesting little idea for making a particular type of LINQ query (basically vote counting) efficient. It was an idea that had occurred to me a few months back, but I hadn&amp;#39;t got round to blogging about it.&lt;/p&gt;  &lt;p&gt;The basic idea was to take a completely empty struct, and use that as the element type in the results of a grouping query - as the struct was empty, it would take no space, therefore &amp;quot;huge&amp;quot; arrays could be created for no cost beyond the fixed array overhead, etc. I carefully checked that the type used for grouping did in fact implement ICollection&amp;lt;T&amp;gt; so that the Count method would be efficient; I wrote sample code which made sure my queries were valid... but I failed to check that the empty struct &lt;em&gt;really&lt;/em&gt; took up no memory.&lt;/p&gt;  &lt;p&gt;Fortunately, I have smart readers, a number of whom pointed out my mistake in very kind terms.&lt;/p&gt;  &lt;p&gt;Ben Voigt gave the reason for the size being 1 in a comment:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;The object identity rules require a unique address for each instance... identity can be shared with super- or sub- class objects (Empty Base Optimization) but the total size of the instance has to be at least 1.&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;This makes perfect sense - it&amp;#39;s just a shame I didn&amp;#39;t realise it before.&lt;/p&gt;  &lt;p&gt;Live and learn, I guess - but apologies for the poorly researched post. I&amp;#39;ll attempt to be more careful next time.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1725262" 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/LINQ/default.aspx">LINQ</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>The "dream book" for C# and .NET</title><link>http://msmvps.com/blogs/jon_skeet/archive/2009/08/20/the-quot-dream-book-quot-for-c-and-net.aspx</link><pubDate>Thu, 20 Aug 2009 16:57:40 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1716905</guid><dc:creator>skeet</dc:creator><slash:comments>33</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/jon_skeet/rsscomments.aspx?PostID=1716905</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/jon_skeet/commentapi.aspx?PostID=1716905</wfw:comment><comments>http://msmvps.com/blogs/jon_skeet/archive/2009/08/20/the-quot-dream-book-quot-for-c-and-net.aspx#comments</comments><description>&lt;p&gt;This morning I &lt;a href="http://twitter.com/jonskeet/status/3424128643"&gt;showed my hand a little on Twitter&lt;/a&gt;. I&amp;#39;ve had a dream for a long time about the ultimate C# book. It&amp;#39;s a dream based on &lt;a href="http://www.amazon.com/dp/0321356683"&gt;Effective Java&lt;/a&gt;, which is my favourite Java book, along with my experiences of writing C# in Depth.&lt;/p&gt;  &lt;p&gt;Effective Java is written by Josh Bloch, who is an absolute giant in the Java world... and that&amp;#39;s both the problem and the opportunity. There&amp;#39;s no-one of quite the equivalent stature in the .NET world. Instead, there are many very smart people, a lot of whom blog and some of whom have their own books.&lt;/p&gt;  &lt;p&gt;There are &amp;quot;best practices&amp;quot; books, of course: Microsoft&amp;#39;s own Framework Design Guidelines, and Bill Wagner&amp;#39;s &lt;a href="http://www.amazon.com/dp/0321245660"&gt;Effective C#&lt;/a&gt; and &lt;a href="http://www.amazon.com/dp/0321485890"&gt;More Effective C#&lt;/a&gt; being the most obvious examples. I&amp;#39;m in no way trying to knock these books, but I feel we could do even better. The &lt;a href="http://www.amazon.com/dp/0321246756"&gt;Framework Design Guidelines&lt;/a&gt; (also available &lt;a href="http://msdn.microsoft.com/en-us/library/ms229042.aspx"&gt;free to browse on MSDN&lt;/a&gt;) are really about how to create a good API - which is important, but not the be-all-and-end-all for many &lt;em&gt;application&lt;/em&gt; developers who aren&amp;#39;t trying to ship a reusable class library and may well have different concerns. They want to know how to use the &lt;em&gt;language&lt;/em&gt; most effectively, as well as the core types within the framework.&lt;/p&gt;  &lt;p&gt;Bill&amp;#39;s books - and many others which cover the core framework, such as &lt;a href="http://www.amazon.com/dp/0735621632"&gt;CLR via C#&lt;/a&gt;, &lt;a href="http://www.amazon.com/dp/1590598733"&gt;Accelerated C# 2008&lt;/a&gt; and &lt;a href="http://www.amazon.com/dp/0596527578"&gt;C# 3.0 in a Nutshell&lt;/a&gt; - give plenty of advice, but often I&amp;#39;ve felt it&amp;#39;s a little one-sided. Each of these books is the work of a single person (or brothers in the case of Nutshell). Reading them, I&amp;#39;ve often wanted to give present a different point of view - or alternatively, to give a hearty &amp;quot;hear, hear.&amp;quot; I believe that a book giving guidance would benefit greatly from being more of a conversation: where the authors all agree on something, that&amp;#39;s great; where they differ, it would be good to hear about the pros and cons of various approaches. The reader can then weigh up those factors as they apply to each particular real-world scenario.&lt;/p&gt;  &lt;h2&gt;Scope&lt;/h2&gt;  &lt;p&gt;So what would such a book contain? Opinions will vary of course, but &lt;em&gt;I&lt;/em&gt; would like to see:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Effective ways of using language features such as lambda expressions, generic type inference (and indeed generics in general), optional parameters, named arguments and extension methods. Assume that the reader knows &lt;em&gt;roughly&lt;/em&gt; what C# does, but give some extra details around things like iterator blocks and anonymous functions.&lt;/li&gt;    &lt;li&gt;Guidance around class design (in a similar fashion to the FDG, but with more input from others in the community)&lt;/li&gt;    &lt;li&gt;Core framework topics (again, assume the basics are understood):&lt;/li&gt;    &lt;ul&gt;     &lt;li&gt;Resource management (disposal etc)&lt;/li&gt;      &lt;li&gt;Exceptions&lt;/li&gt;      &lt;li&gt;Collections (including LINQ fundamentals)&lt;/li&gt;      &lt;li&gt;Streams&lt;/li&gt;      &lt;li&gt;Text (including internationalization)&lt;/li&gt;      &lt;li&gt;Numeric types&lt;/li&gt;      &lt;li&gt;Time-related APIs&lt;/li&gt;      &lt;li&gt;Concurrency&lt;/li&gt;      &lt;li&gt;Contracts&lt;/li&gt;      &lt;li&gt;AppDomains&lt;/li&gt;      &lt;li&gt;Security&lt;/li&gt;      &lt;li&gt;Performance&lt;/li&gt;   &lt;/ul&gt; &lt;/ul&gt;  &lt;p&gt;I would prefer to avoid anything around the periphery of .NET (WPF, WinForms, ASP.NET, WCF) - I believe those are better handled in different topics.&lt;/p&gt;  &lt;h2&gt;Obstacles and format&lt;/h2&gt;  &lt;p&gt;There&amp;#39;s one big problem with this idea, but I think it may be a saving grace too. Many of the leading authors work for different publishers. Clearly no single publisher is going to attract &lt;em&gt;all&lt;/em&gt; the best minds in the C# and .NET world. So how could this work in practice? Well...&lt;/p&gt;  &lt;p&gt;Imagine a web site for the book, paid for jointly by all interested publishers. The web site would be the foremost delivery mechanism for the content, both to browse and probably to download in formats appropriate for offline reading (PDF etc). The content would be edited in a collaborative style obviously, but exactly how that would work is a detail to be thrashed out. If you&amp;#39;ve read the annotated C# or CLI specifications, they have about the right feel - opinions can be attributed in places, but not &lt;em&gt;everything&lt;/em&gt; has a label.&lt;/p&gt;  &lt;p&gt;Any contributing publisher could &lt;em&gt;also&lt;/em&gt; take the material and publish it as hard copy if they so wished. Quite how this would work - with potentially multiple hard copy editions of the same content - would be interesting to see. There&amp;#39;s another reason against hard copy ever appearing though, which is that it would be immovable. I&amp;#39;d like to see this work evolve as new features appear and as more best practices are discovered. Publishers could monetize the web site via adverts, possibly according to how much they&amp;#39;re kicking into the site.&lt;/p&gt;  &lt;p&gt;I don&amp;#39;t know how the authors would get paid, admittedly, and that&amp;#39;s another problem. Would this cannibalize the sales of the books listed earlier? It wouldn&amp;#39;t make them redundant - certainly not for the Nutshell type of book, which teaches the basics as well as giving guidance. It would hit Effective C# harder, I suspect - and I apologise to Bill Wagner in advance; if this ever takes off and it hurts his bottom line, I&amp;#39;m very sorry - I think it&amp;#39;s in a good cause though.&lt;/p&gt;  &lt;h2&gt;Dream Team&lt;/h2&gt;  &lt;p&gt;So who would contribute to this? Part of me would like to say &amp;quot;anyone and everyone&amp;quot; in a Wikipedia kind of approach - but I think that practically, it makes sense for industry experts to take their places. (A good feedback/comments mechanism for anyone to use would be crucial, however.) Here&amp;#39;s a list which isn&amp;#39;t meant to be exhaustive, but would make me happy - please don&amp;#39;t take offence if your name isn&amp;#39;t on here but should be, and I wouldn&amp;#39;t expect &lt;em&gt;all&lt;/em&gt; of these people to be interested anyway.&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Anders Hejlsberg&lt;/li&gt;    &lt;li&gt;Eric Lippert&lt;/li&gt;    &lt;li&gt;Mads Torgersen&lt;/li&gt;    &lt;li&gt;Don Box&lt;/li&gt;    &lt;li&gt;Brad Abrams&lt;/li&gt;    &lt;li&gt;Krzysztof Cwalina&lt;/li&gt;    &lt;li&gt;Joe Duffy&lt;/li&gt;    &lt;li&gt;Vance Morrison&lt;/li&gt;    &lt;li&gt;Rico Mariani&lt;/li&gt;    &lt;li&gt;Erik Meijer&lt;/li&gt;    &lt;li&gt;Don Symes&lt;/li&gt;    &lt;li&gt;Wes Dyer&lt;/li&gt;    &lt;li&gt;Jeff Richter&lt;/li&gt;    &lt;li&gt;Joe and Ben Albahari&lt;/li&gt;    &lt;li&gt;Andrew Troelsen&lt;/li&gt;    &lt;li&gt;Bill Wagner&lt;/li&gt;    &lt;li&gt;Trey Nash&lt;/li&gt;    &lt;li&gt;Mark Michaelis&lt;/li&gt;    &lt;li&gt;Jon Skeet (yeah, I want to contribute if I can)&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;I imagine &amp;quot;principal&amp;quot; authors for specific topics (e.g. Joe Duffy for concurrency) but with all the authors dropping in comments in other places too.&lt;/p&gt;  &lt;h2&gt;Dream or reality?&lt;/h2&gt;  &lt;p&gt;I have no idea whether this will ever happen or not. I&amp;#39;d dearly love it to, and I&amp;#39;ve spoken to a few people before today who&amp;#39;ve been encouraging about the idea. I haven&amp;#39;t been putting any work into getting it off the ground - don&amp;#39;t worry, it&amp;#39;s not been delaying the second edition of C# in Depth. One day though, one day...&lt;/p&gt;  &lt;p&gt;Am I being hopelessly naïve to even consider such a venture? Is the scope too broad? Is the content valuable but not money-making? We&amp;#39;ll see.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1716905" 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></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>A different approach to inappropriate defaults</title><link>http://msmvps.com/blogs/jon_skeet/archive/2009/05/14/a-different-approach-to-inappropriate-defaults.aspx</link><pubDate>Thu, 14 May 2009 17:03:52 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1692419</guid><dc:creator>skeet</dc:creator><slash:comments>9</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/jon_skeet/rsscomments.aspx?PostID=1692419</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/jon_skeet/commentapi.aspx?PostID=1692419</wfw:comment><comments>http://msmvps.com/blogs/jon_skeet/archive/2009/05/14/a-different-approach-to-inappropriate-defaults.aspx#comments</comments><description>&lt;p&gt;I&amp;#39;ve had a couple of bug reports about &lt;a href="http://code.google.com/p/protobuf-csharp-port/"&gt;my Protocol Buffers port&lt;/a&gt; - both nicely detailed, and one including a patch to fix it. (It&amp;#39;s only due to my lack of timeliness in actually submitting the change that the second bug report occurred. Oops.)&lt;/p&gt;  &lt;p&gt;The bug was in text formatting (although it also affected parsing). I was using the default &lt;code&gt;ToString&lt;/code&gt; behaviour for numbers, which meant that floats and doubles were being formatted as &amp;quot;50,15&amp;quot; in Germany instead of &amp;quot;50.15&amp;quot;. The unit tests caught this, but only if you ran them on a machine with an appropriate default culture.&lt;/p&gt;  &lt;p&gt;Aaargh. I&amp;#39;ve been struggling with a similar problem in a library I &lt;em&gt;can&amp;#39;t&lt;/em&gt; change, which uses the system default time zone for various calculations in Java. When you&amp;#39;re running server code, the default time zone is almost never the one you want to use, and it certainly isn&amp;#39;t in my case.&lt;/p&gt;  &lt;p&gt;A similar problem is Java&amp;#39;s decision to use the system default encoding in all kinds of bizarre places - &lt;code&gt;FileReader&lt;/code&gt; doesn&amp;#39;t even let you specify the encoding, which makes it almost entirely useless in my view.&lt;/p&gt;  &lt;p&gt;So I&amp;#39;ve been wondering how we could fix this and problems like it. One option is to completely remove the defaults. If you always &lt;em&gt;had&lt;/em&gt; to pass in a &lt;code&gt;CultureInfo&lt;/code&gt;/&lt;code&gt;Locale&lt;/code&gt;, &lt;code&gt;TimeZoneInfo&lt;/code&gt;/&lt;code&gt;TimeZone&lt;/code&gt;, &lt;code&gt;Encoding&lt;/code&gt;/&lt;code&gt;Charset&lt;/code&gt; when you call any method which might be culturally sensitive.&lt;/p&gt;  &lt;h3&gt;Making life easier (in .NET)&lt;/h3&gt;  &lt;p&gt;It strikes me that .NET has a useful abstraction here: the assembly as the unit of deployment. (Java&amp;#39;s closest equivalent is probably a jar file, which probably gets messier.)&lt;/p&gt;  &lt;p&gt;Within one assembly, I suspect in many cases you always want to make the same decision. For example, in protocol buffers I would like to use the invariant culture all the time. It would be nice if I could say that, and then get the right behaviour by default. Here are the options I&amp;#39;d like to be able to apply (for each of culture, time zone and character encoding - there may be others):&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Use a culture-neutral default (the invariant culture, UTF-8, UTC)&lt;/li&gt;    &lt;li&gt;Use a specific set of values (e.g. en-GB, Windows-1252, &amp;quot;Europe/London&amp;quot;)&lt;/li&gt;    &lt;li&gt;Use the system default values&lt;/li&gt;    &lt;li&gt;Use whatever the calling assembly is using&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Of course you should still have the option of specifying overrides on a per call basis, but I think this &lt;em&gt;might&lt;/em&gt; be a way forward.&lt;/p&gt;  &lt;p&gt;Thoughts? I realise it&amp;#39;s almost certainly too late for this to actually be implemented now, but would it have been a good idea? Or is it just an alternative source of confusion?&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1692419" 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/Java/default.aspx">Java</category><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/Wacky+Ideas/default.aspx">Wacky Ideas</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>Breaking Liskov</title><link>http://msmvps.com/blogs/jon_skeet/archive/2009/03/16/breaking-liskov.aspx</link><pubDate>Mon, 16 Mar 2009 17:48:04 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1678395</guid><dc:creator>skeet</dc:creator><slash:comments>32</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/jon_skeet/rsscomments.aspx?PostID=1678395</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/jon_skeet/commentapi.aspx?PostID=1678395</wfw:comment><comments>http://msmvps.com/blogs/jon_skeet/archive/2009/03/16/breaking-liskov.aspx#comments</comments><description>&lt;p&gt;Very recently, &lt;a href="http://news.bbc.co.uk/1/hi/technology/7937010.stm"&gt;Barbara Liskov won the Turing award&lt;/a&gt;, which makes it a highly appropriate time to ponder when it&amp;#39;s reasonable to ignore her most famous piece of work, the &lt;a href="http://en.wikipedia.org/wiki/Liskov_substitution_principle"&gt;Liskov Substitution (or Substitutability) Principle&lt;/a&gt;. This is not idle speculation: I&amp;#39;ve had a feature request for &lt;a href="http://pobox.com/~skeet/csharp/miscutil"&gt;MiscUtil&lt;/a&gt;. The request makes sense, simplifies the code, and is good all round - but it breaks substitutability &lt;em&gt;and&lt;/em&gt; documented APIs.&lt;/p&gt; &lt;p&gt;The substitutability principle is in some ways just common sense. It says (in paraphrase) that if your code works for some base type T, it should be able to work with subtype of T, S. If it doesn&amp;#39;t, S is breaking substitutability. This principle is at the heart of inheritance and polymorphism - I should be able to use a Stream without knowing the details of what its underlying storage is, for example.&lt;/p&gt; &lt;p&gt;Liskov&amp;#39;s formulation is:&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;&lt;i&gt;Let &lt;i&gt;q&lt;/i&gt;(&lt;i&gt;x&lt;/i&gt;) be a property provable about objects &lt;i&gt;x&lt;/i&gt; of type &lt;i&gt;T&lt;/i&gt;. Then &lt;i&gt;q&lt;/i&gt;(&lt;i&gt;y&lt;/i&gt;) should be true for objects &lt;i&gt;y&lt;/i&gt; of type &lt;i&gt;S&lt;/i&gt; where &lt;i&gt;S&lt;/i&gt; is a subtype of &lt;i&gt;T&lt;/i&gt;.&lt;/i&gt;&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;So, that&amp;#39;s the rule. Sounds like a good idea, right?&lt;/p&gt; &lt;h3&gt;Breaking BinaryReader&amp;#39;s contract&lt;/h3&gt; &lt;p&gt;My case in point is EndianBinaryReader (and EndianBinaryWriter, but the arguments will all be the same - it&amp;#39;s better to focus on a single type). This is simply an equivalent to &lt;a href="http://msdn.microsoft.com/en-us/library/system.io.binaryreader.aspx"&gt;System.IO.BinaryReader&lt;/a&gt;, but it lets you specify the endianness to use when converting values.&lt;/p&gt; &lt;p&gt;Currently, EndianBinaryReader is a completely separate class to BinaryReader. They have no inheritance relationship. However, as it happens, BinaryReader isn&amp;#39;t sealed, and all of the appropriate methods are virtual. So, can we make EndianBinaryReader derive from BinaryReader and use it as a drop-in replacement? Well... that&amp;#39;s where the trouble starts.&lt;/p&gt; &lt;p&gt;There&amp;#39;s no difficulty &lt;em&gt;technically&lt;/em&gt; in doing it. The implementation is fairly straightforward - indeed, it means we can drop a bunch of methods from EndianBinaryReader and let BinaryReader handle it instead. (This is particularly handy for text, which is fiddly to get right.) I currently have the code in another branch, and it works fine.&lt;/p&gt; &lt;h3&gt;And I would have gotten away with it if it weren&amp;#39;t for that pesky inheritance...&lt;/h3&gt; &lt;p&gt;The problem is whether or not it&amp;#39;s the right thing to do. To start with, it breaks Liskov&amp;#39;s substitutability principle, if the &amp;quot;property&amp;quot; we consider is &amp;quot;the result of calling ReadInt32 when the next four bytes of the underlying stream are 00, 00, 00, 01&amp;quot; for example. Not having read Liskov&amp;#39;s paper for myself (I really should, some time) I&amp;#39;m not sure whether this is the intended kind of use or not. More on that later.&lt;/p&gt; &lt;p&gt;The second problem is that it contradicts the documentation for BinaryReader. For example, the &lt;a href="http://msdn.microsoft.com/en-us/library/system.io.binaryreader.readint32.aspx"&gt;docs for ReadInt32&lt;/a&gt; state: &amp;quot;&lt;a href="http://msdn.microsoft.com/en-us/library/system.io.binaryreader.aspx"&gt;BinaryReader&lt;/a&gt; reads this data type in little-endian format.&amp;quot; That&amp;#39;s a tricky bit of documentation to understand precisely - it&amp;#39;s correct for BinaryReader itself, but does that mean it should be true for all subclasses too?&lt;/p&gt; &lt;p&gt;When I&amp;#39;ve written in various places about the problems of inheritance, and why if you design a class to be unsealed that means doing more design work, this is the kind of thing I&amp;#39;ve been talking about. How much detail does it make sense to specify here? How much leeway is there for classes overriding ReadInt32? Could a different implementation read a &amp;quot;compressed&amp;quot; Int32 instead of always reading four bytes, for example? Should the client care, if they make sure they&amp;#39;ve obtained an appropriate BinaryReader for their data source in the first place? This is basically the same as asking how strictly we should apply Liskov&amp;#39;s substitutability principle. If two types are the same in &lt;em&gt;every&lt;/em&gt; property, surely we can&amp;#39;t distinguish between them at all.&lt;/p&gt; &lt;p&gt;I wonder whether most design questions of inheritance basically boil down to defining which properties should obey Liskov&amp;#39;s substitutability principle and which needn&amp;#39;t, for the type you&amp;#39;re designing. Of course, it&amp;#39;s not just black and white - there will always be exceptions and awkward points. Programming is often about nuance, even if we might wish that not to be the case.&lt;/p&gt; &lt;h3&gt;Blow it, let&amp;#39;s do it anyway...&lt;/h3&gt; &lt;p&gt;Coming back to BinaryReader, I &lt;em&gt;think&lt;/em&gt; (unless I can be persuaded otherwise) that the benefits from going against the documentation (and strict substitutability) outweigh the downsides. In particular, BinaryReaders don&amp;#39;t tend to be passed around in my experience - the code which creates it is usually the code which uses it too, or it&amp;#39;s at least closely related. The risk of breaking code by passing it a BinaryReader using an unexpected endianness is therefore quite low, even though it&amp;#39;s theoretically possible.&lt;/p&gt; &lt;p&gt;So, am I miles off track? This is for a class library, after all - should I be more punctilious about playing by the rules? Or is pragmatism the more important principle here?&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1678395" 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></item><item><title>RFID: What I really want it for</title><link>http://msmvps.com/blogs/jon_skeet/archive/2009/01/24/rfid-what-i-really-want-it-for.aspx</link><pubDate>Sat, 24 Jan 2009 19:28:40 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1665601</guid><dc:creator>skeet</dc:creator><slash:comments>9</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/jon_skeet/rsscomments.aspx?PostID=1665601</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/jon_skeet/commentapi.aspx?PostID=1665601</wfw:comment><comments>http://msmvps.com/blogs/jon_skeet/archive/2009/01/24/rfid-what-i-really-want-it-for.aspx#comments</comments><description>&lt;p&gt;This isn&amp;#39;t really coding related, but it&amp;#39;s &lt;em&gt;technology&lt;/em&gt; related at least. There&amp;#39;s been a lot of fuss made about how great or awful RFID is and will be in the future, in terms of usefuless and privacy invasion respectively. There&amp;#39;s one use which I haven&amp;#39;t seen discussed, but which seems pretty obvious to me - but with further enhancements available.&lt;/p&gt; &lt;p&gt;Basically, I want RFID on clothes to tell me useful stuff. Suppose each item of clothing were uniquely tagged, and you had a bunch of scanners in your home linked up to one system which stored metadata about the clothes. Suddenly the following tasks become easier:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Working out which wash cycle to use for a whole washing basket. Can&amp;#39;t see the dark sock hidden in the white wash? The RFID scanner could alert you to it. Likewise tumbledrying - no need to check each item separately, just attach the scanner over the tumbledryer door and wait for it to beep as you try to put something in which shouldn&amp;#39;t be tumbled.&lt;/li&gt; &lt;li&gt;Separating clothes to put them away after they&amp;#39;re clean and dry. Admittedly this is more of a chore for our household than others (with twin boys and an older brother, where some items of clothing could belong to any of them) but it would be really, &lt;em&gt;really&lt;/em&gt; useful for us.&lt;/li&gt; &lt;li&gt;Remembering who you&amp;#39;ve borrowed which clothes from. Kids grow out of clothes very quickly; we have a number of friends who lend us clothes from their children, and likewise we lend plenty of clothes to them and others. You&amp;#39;ve then got to remember what you borrowed from who, which can become tricky when you&amp;#39;ve got a loft full of bags of clothing. Wouldn&amp;#39;t it be nice to just &amp;quot;label&amp;quot; all the clothes in a bag with the owner&amp;#39;s name when you first receive them, and then just pass a scanner near everything quickly later on?&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;The privacy issues of all of this would have to be worked out carefully (as the simplest solution would allow your movements to be traced just by which clothes you&amp;#39;re wearing) but if it &lt;em&gt;does&lt;/em&gt; end up being possible, I&amp;#39;ll be hugely grateful for this.&lt;/p&gt; &lt;p&gt;(Next up, benchmarking of for vs foreach in various situations. In other words, back to our regular schedule :)&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1665601" 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/Wacky+Ideas/default.aspx">Wacky Ideas</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>Horrible grotty hack: returning an anonymous type instance</title><link>http://msmvps.com/blogs/jon_skeet/archive/2009/01/09/horrible-grotty-hack-returning-an-anonymous-type-instance.aspx</link><pubDate>Fri, 09 Jan 2009 07:52:14 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1659812</guid><dc:creator>skeet</dc:creator><slash:comments>21</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/jon_skeet/rsscomments.aspx?PostID=1659812</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/jon_skeet/commentapi.aspx?PostID=1659812</wfw:comment><comments>http://msmvps.com/blogs/jon_skeet/archive/2009/01/09/horrible-grotty-hack-returning-an-anonymous-type-instance.aspx#comments</comments><description>&lt;p&gt;One of the reasons I don&amp;#39;t view anonymous types as being too bad is that they&amp;#39;re nicely confined to methods. You can&amp;#39;t declare the type that you&amp;#39;re returning from a method if it&amp;#39;s anonymous (or if one of its type arguments is generic, e.g. a &lt;code&gt;List&amp;lt;T&amp;gt;&lt;/code&gt; where &lt;code&gt;T&lt;/code&gt; is an anonymous type and &lt;code&gt;T&lt;/code&gt; isn&amp;#39;t a type parameter to the method itself). However, you &lt;em&gt;can&lt;/em&gt; get around this if you&amp;#39;re sneaky.&lt;/p&gt; &lt;p&gt;I&amp;#39;ve always known that it&amp;#39;s perfectly easy to return an instance of an anonymous type by declaring that the method will return &lt;code&gt;object&lt;/code&gt;. However, it hadn&amp;#39;t occurred to me before today that you can actually cast back to that type afterwards. Of course, you can&amp;#39;t just use a normal cast expression - that requires the name of the type to be known at compile-time. But you can do a cast in a generic method... and you can use type inference to supply a type argument... and two anonymous type instance creation expressions will use the same type within the same assembly if the order, names and types of the properties are the same.&lt;/p&gt; &lt;p&gt;Behold the evil cheesecake factory!&lt;/p&gt; &lt;div class="code"&gt;&lt;span class="Namespace"&gt;using&lt;/span&gt; System;&lt;br /&gt;&lt;br /&gt;&lt;span class="Modifier"&gt;static&lt;/span&gt;&amp;nbsp;&lt;span class="ReferenceType"&gt;class&lt;/span&gt; GrottyHacks&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="Modifier"&gt;internal&lt;/span&gt;&amp;nbsp;&lt;span class="Modifier"&gt;static&lt;/span&gt; T Cast&amp;lt;T&amp;gt;(&lt;span class="ReferenceType"&gt;object&lt;/span&gt; target, T example)&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; (T) target;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span class="ReferenceType"&gt;class&lt;/span&gt; CheesecakeFactory&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="Modifier"&gt;static&lt;/span&gt;&amp;nbsp;&lt;span class="ReferenceType"&gt;object&lt;/span&gt; CreateCheesecake()&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; { Fruit=&lt;span class="String"&gt;&amp;quot;Strawberry&amp;quot;&lt;/span&gt;, Topping=&lt;span class="String"&gt;&amp;quot;Chocolate&amp;quot;&lt;/span&gt; };&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="Modifier"&gt;static&lt;/span&gt;&amp;nbsp;&lt;span class="ValueType"&gt;void&lt;/span&gt; Main()&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="ReferenceType"&gt;object&lt;/span&gt; weaklyTyped = CreateCheesecake();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="Linq"&gt;var&lt;/span&gt; stronglyTyped = GrottyHacks.Cast(weaklyTyped,&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;new&lt;/span&gt; { Fruit=&lt;span class="String"&gt;&amp;quot;&amp;quot;&lt;/span&gt;, Topping=&lt;span class="String"&gt;&amp;quot;&amp;quot;&lt;/span&gt; });&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; Console.WriteLine(&lt;span class="String"&gt;&amp;quot;Cheesecake: {0} ({1})&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; stronglyTyped.Fruit, stronglyTyped.Topping);&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; }&lt;br /&gt;} &lt;/div&gt; &lt;p&gt;The important thing to note here is that the &lt;code&gt;stronglyTyped&lt;/code&gt; variable really is of the same anonymous type as the one used in the &lt;code&gt;CreateCheesecake&lt;/code&gt; method. When we use the &lt;code&gt;Fruit&lt;/code&gt; and &lt;code&gt;Topping&lt;/code&gt; properties in the last statement, that&amp;#39;s checked at compile-time.&lt;/p&gt; &lt;p&gt;Of course, it all goes pear-shaped if you make the slightest of errors when giving the &lt;code&gt;Cast&lt;/code&gt; method an example of what you want to cast to - if you got the order of the properties wrong, for example, the code would still compile, but the cast would throw an exception at execution time.&lt;/p&gt; &lt;p&gt;How useful is this? Ooh, probably not at all. &lt;strong&gt;Please do not use this &amp;quot;technique&amp;quot; in your code. If you do, at least don&amp;#39;t mention my name anywhere near it.&lt;/strong&gt; It&amp;#39;s all fun though, isn&amp;#39;t it?&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1659812" 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></item><item><title>Value types and parameterless constructors</title><link>http://msmvps.com/blogs/jon_skeet/archive/2008/12/10/value-types-and-parameterless-constructors.aspx</link><pubDate>Wed, 10 Dec 2008 17:55:40 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1656405</guid><dc:creator>skeet</dc:creator><slash:comments>11</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/jon_skeet/rsscomments.aspx?PostID=1656405</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/jon_skeet/commentapi.aspx?PostID=1656405</wfw:comment><comments>http://msmvps.com/blogs/jon_skeet/archive/2008/12/10/value-types-and-parameterless-constructors.aspx#comments</comments><description>&lt;p&gt;There have been a couple of questions on StackOverflow about value types and parameterless constructors:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href="http://stackoverflow.com/questions/203695"&gt;Structure vs Class in C#&lt;/a&gt;  &lt;li&gt;&lt;a href="http://stackoverflow.com/questions/333829"&gt;Why can’t I define a default constructor for a struct in .NET&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;I learned quite a bit when answering both of these. When a &lt;a href="http://stackoverflow.com/questions/354136"&gt;further question&lt;/a&gt; about the default value of a type (particularly with respect to generics) came up, I thought it would be worth delving into a bit more depth. Very little of this is actually relevant most of the time, but it&amp;#39;s interesting nonetheless.&lt;/p&gt; &lt;p&gt;I won&amp;#39;t go over most of the details I discovered in &lt;a href="http://stackoverflow.com/questions/203695/structure-vs-class-in-c#204009"&gt;my answer to the first question&lt;/a&gt;,&amp;nbsp; but if you&amp;#39;re interested in the IL generated by the statement &amp;quot;x = new Guid();&amp;quot; then have a look there for more details.&lt;/p&gt; &lt;p&gt;Let&amp;#39;s start off with the first and most important thing I&amp;#39;ve learned about value types recently:&lt;/p&gt; &lt;h3&gt;Yes, you &lt;em&gt;can&lt;/em&gt; write a parameterless constructor for a value type in .NET&lt;/h3&gt; &lt;p&gt;I very carefully wrote &amp;quot;in .NET&amp;quot; there - &amp;quot;in C#&amp;quot; would have been incorrect. I had always believed that the CLI spec prohibited value types from having parameterless constructors. (The C# spec used the terminology in a slightly different way - it treats &lt;em&gt;all&lt;/em&gt; value types as having a parameterless constructor. This makes the language more consistent for the most part, but it does give rise to some interesting behaviour which we&amp;#39;ll see later on.)&lt;/p&gt; &lt;p&gt;It turns out that if you write your value type in IL, you can provide your own parameterless constructor with custom code without ilasm complaining at all. It&amp;#39;s possible that other languages targeting the CLI allow you to do this as well, but as I don&amp;#39;t know any, I&amp;#39;ll stick to IL. Unfortunately I don&amp;#39;t know IL terribly well, so I thought I&amp;#39;d just start off with some C# and go from there:&lt;/p&gt; &lt;div class="code"&gt;&lt;span class="Modifier"&gt;public&lt;/span&gt;&amp;nbsp;&lt;span class="ValueType"&gt;struct&lt;/span&gt; Oddity&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="Modifier"&gt;public&lt;/span&gt; Oddity(&lt;span class="ValueType"&gt;int&lt;/span&gt; removeMe)&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; System.Console.WriteLine(&lt;span class="String"&gt;&amp;quot;Oddity constructor called&amp;quot;&lt;/span&gt;);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;} &lt;/div&gt; &lt;p&gt;I compiled that into its own class library, and then disassembled it with &lt;code&gt;ildasm /out:Oddity.il Oddity.dll&lt;/code&gt;. After changing the constructor to be parameterless, removing a few comments, and removing some compiler-generated assembly attributes) I ended up with this IL:&lt;/p&gt;&lt;pre&gt;.assembly extern mscorlib
{
  .publickeytoken = (B7 7A 5C 56 19 34 E0 89 )  
  .ver 2:0:0:0
}
.assembly Oddity
{
  .hash algorithm 0x00008004
  .ver 0:0:0:0
}
.module Oddity.dll
.imagebase 0x00400000
.file alignment 0x00000200
.stackreserve 0x00100000
.subsystem 0x0003
.corflags 0x00000001

.class public sequential ansi sealed beforefieldinit Oddity
       extends [mscorlib]System.ValueType
{
  .pack 0
  .size 1
  .method public hidebysig specialname rtspecialname 
          instance void  .ctor() cil managed
  {
    .maxstack  8
    IL_0000:  nop
    IL_0001:  ldstr      &amp;quot;Oddity constructor called&amp;quot;
    IL_0006:  call       void [mscorlib]System.Console::WriteLine(string)
    IL_000b:  nop
    IL_000c:  ret
  }
}
&lt;/pre&gt;
&lt;p&gt;I reassembled this with &lt;code&gt;ilasm /dll /out:Oddity.dll Oddity.il&lt;/code&gt;. So far, so good. We have a value type with a custom constructor in a class library. It doesn&amp;#39;t do anything particularly clever - it just logs that it&amp;#39;s been called. That&amp;#39;s enough for our test program.&lt;/p&gt;
&lt;h2&gt;When does the parameterless constructor get called?&lt;/h2&gt;
&lt;p&gt;There are various things one &lt;i&gt;could&lt;/i&gt; investigate about parameterless constructors, but I&amp;#39;m mostly interested in when they get called. The test application is reasonably simple, but contains lots of cases - each writes to the console what it&amp;#39;s about to do, then does something which &lt;i&gt;might&lt;/i&gt; call the constructor. Without further ado:&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.CompilerServices;&lt;br /&gt;&lt;br /&gt;&lt;span class="ReferenceType"&gt;class&lt;/span&gt; Test&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="Modifier"&gt;static&lt;/span&gt; Oddity staticField;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Oddity instanceField;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="Modifier"&gt;static&lt;/span&gt;&amp;nbsp;&lt;span class="ValueType"&gt;void&lt;/span&gt; Main()&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; Report(&lt;span class="String"&gt;&amp;quot;Declaring local variable&amp;quot;&lt;/span&gt;);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Oddity localDeclarationOnly;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="InlineComment"&gt;// No variables within the value, so we can use it&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="InlineComment"&gt;// without inializing anything&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Report(&lt;span class="String"&gt;&amp;quot;Boxing&amp;quot;&lt;/span&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; o = localDeclarationOnly;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="InlineComment"&gt;// Just make sure it&amp;#39;s really done it&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Report(o.ToString());&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Report(&lt;span class="String"&gt;&amp;quot;new Oddity() - set local variable&amp;quot;&lt;/span&gt;);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Oddity local = &lt;span class="Keyword"&gt;new&lt;/span&gt; Oddity();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Report(&lt;span class="String"&gt;&amp;quot;Create instance of Test - contains instance variable&amp;quot;&lt;/span&gt;);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Test t = &lt;span class="Keyword"&gt;new&lt;/span&gt; Test();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Report(&lt;span class="String"&gt;&amp;quot;new Oddity() - set instance field&amp;quot;&lt;/span&gt;);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; t.instanceField = &lt;span class="Keyword"&gt;new&lt;/span&gt; Oddity();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Report(&lt;span class="String"&gt;&amp;quot;new Oddity() - set static field&amp;quot;&lt;/span&gt;);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; staticField = &lt;span class="Keyword"&gt;new&lt;/span&gt; Oddity();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Report(&lt;span class="String"&gt;&amp;quot;new Oddity[10]&amp;quot;&lt;/span&gt;);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; o = &lt;span class="Keyword"&gt;new&lt;/span&gt; Oddity[10];&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Report(&lt;span class="String"&gt;&amp;quot;Passing argument to method&amp;quot;&lt;/span&gt;);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; MethodWithParameter(local);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; GenericMethod&amp;lt;Oddity&amp;gt;();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; GenericMethod2&amp;lt;Oddity&amp;gt;();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Report(&lt;span class="String"&gt;&amp;quot;Activator.CreateInstance(typeof(Oddity))&amp;quot;&lt;/span&gt;);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Activator.CreateInstance(&lt;span class="Keyword"&gt;typeof&lt;/span&gt;(Oddity));&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Report(&lt;span class="String"&gt;&amp;quot;Activator.CreateInstance&amp;lt;Oddity&amp;gt;()&amp;quot;&lt;/span&gt;);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Activator.CreateInstance&amp;lt;Oddity&amp;gt;();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; [MethodImpl(MethodImplOptions.NoInlining)]&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="Modifier"&gt;static&lt;/span&gt;&amp;nbsp;&lt;span class="ValueType"&gt;void&lt;/span&gt; MethodWithParameter(Oddity oddity)&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="InlineComment"&gt;// No need to do anything&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="Modifier"&gt;static&lt;/span&gt;&amp;nbsp;&lt;span class="ValueType"&gt;void&lt;/span&gt; GenericMethod&amp;lt;T&amp;gt;() &lt;span class="Linq"&gt;where&lt;/span&gt; T : &lt;span class="Keyword"&gt;new&lt;/span&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; Report(&lt;span class="String"&gt;&amp;quot;default(T) in generic method with new() constraint&amp;quot;&lt;/span&gt;);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; T t = &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; Report(&lt;span class="String"&gt;&amp;quot;new T() in generic method with new() constraint&amp;quot;&lt;/span&gt;);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; t = &lt;span class="Keyword"&gt;new&lt;/span&gt; T();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="Modifier"&gt;static&lt;/span&gt;&amp;nbsp;&lt;span class="ValueType"&gt;void&lt;/span&gt; GenericMethod2&amp;lt;T&amp;gt;() &lt;span class="Linq"&gt;where&lt;/span&gt; T : &lt;span class="ValueType"&gt;struct&lt;/span&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; Report(&lt;span class="String"&gt;&amp;quot;default(T) in generic method with struct constraint&amp;quot;&lt;/span&gt;);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; T t = &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; Report(&lt;span class="String"&gt;&amp;quot;new T() in generic method with struct constraint&amp;quot;&lt;/span&gt;);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; t = &lt;span class="Keyword"&gt;new&lt;/span&gt; T();&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;static&lt;/span&gt;&amp;nbsp;&lt;span class="ValueType"&gt;void&lt;/span&gt; Report(&lt;span class="ReferenceType"&gt;string&lt;/span&gt; text)&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; Console.WriteLine(text);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;} &lt;/div&gt;
&lt;p&gt;And here are the results:&lt;/p&gt;
&lt;div class="output"&gt;Declaring local variable&lt;br /&gt;Boxing&lt;br /&gt;Oddity&lt;br /&gt;new Oddity() - set local variable&lt;br /&gt;Oddity constructor called&lt;br /&gt;Create instance of Test - contains instance variable&lt;br /&gt;new Oddity() - set instance field&lt;br /&gt;Oddity constructor called&lt;br /&gt;new Oddity() - set static field&lt;br /&gt;Oddity constructor called&lt;br /&gt;new Oddity[10]&lt;br /&gt;Passing argument to method&lt;br /&gt;default(T) in generic method with new() constraint&lt;br /&gt;new T() in generic method with new() constraint&lt;br /&gt;default(T) in generic method with struct constraint&lt;br /&gt;new T() in generic method with struct constraint&lt;br /&gt;Activator.CreateInstance(typeof(Oddity))&lt;br /&gt;Oddity constructor called&lt;br /&gt;Activator.CreateInstance&amp;lt;Oddity&amp;gt;()&lt;br /&gt;Oddity constructor called &lt;/div&gt;
&lt;p&gt;So, to split these out: &lt;/p&gt;
&lt;h2&gt;Operations which &lt;i&gt;do&lt;/i&gt; call the constructor&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;new Oddity() - whatever we&amp;#39;re storing the result in. This isn&amp;#39;t much of a surprise. What may surprise you is that it gets called even if you compile Test.cs against the original Oddity.dll (without the custom parameterless constructor) and then just rebuild Oddity.dll. 
&lt;li&gt;&lt;code&gt;Activator.CreateInstance&amp;lt;T&amp;gt;()&lt;/code&gt; and &lt;code&gt;Activator.CreateInstance(Type)&lt;/code&gt;. I wouldn&amp;#39;t be particular surprised by this either way. &lt;/li&gt;&lt;/ul&gt;
&lt;h2&gt;Operations which &lt;i&gt;don&amp;#39;t&lt;/i&gt; call the constructor&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Just declaring a variable, whether local, static or instance 
&lt;li&gt;Boxing 
&lt;li&gt;Creating an array - good job, as this could be a real performance killer 
&lt;li&gt;Using &lt;code&gt;default(T) in a generic method - this one didn&amp;#39;t surprise me&lt;/code&gt; 
&lt;li&gt;Using &lt;code&gt;new T()&lt;/code&gt; in a generic method - this one really &lt;i&gt;did&lt;/i&gt; surprise me. Not only is it counterintuitive, but in IL it just calls &lt;code&gt;Activator.CreateInstance&amp;lt;T&amp;gt;()&lt;/code&gt;. What&amp;#39;s the difference between this and calling &lt;code&gt;Activator.CreateInstance&amp;lt;Oddity&amp;gt;()&lt;/code&gt;? I really don&amp;#39;t understand.&lt;/li&gt;&lt;/ul&gt;
&lt;h2&gt;Conclusions&lt;/h2&gt;
&lt;p&gt;Well, I&amp;#39;m still glad that C# doesn&amp;#39;t let us define our own parameterless constructors for value types, given the behaviour. The main reason for using it - as far as I&amp;#39;ve seen - it to make sure that the &amp;quot;default value&amp;quot; for a type is sensible. Given that it&amp;#39;s possible to get a usable value of the type without the constructor being called, this wouldn&amp;#39;t work anyway. Writing such a constructor would be like making a value type mutable - almost always a bad idea.&lt;/p&gt;
&lt;p&gt;However, it&amp;#39;s nice to know it&amp;#39;s &lt;em&gt;possible&lt;/em&gt;, just on the grounds that learning new things is always a good thing. And at least next time someone asks a similar question, I&amp;#39;ll have somewhere to point them...&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1656405" 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/CSharpDevCenter/default.aspx">CSharpDevCenter</category><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/CSharpDev/default.aspx">CSharpDev</category></item><item><title>Redesigning System.Object/java.lang.Object</title><link>http://msmvps.com/blogs/jon_skeet/archive/2008/12/05/redesigning-system-object-java-lang-object.aspx</link><pubDate>Fri, 05 Dec 2008 17:52:44 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1655908</guid><dc:creator>skeet</dc:creator><slash:comments>31</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/jon_skeet/rsscomments.aspx?PostID=1655908</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/jon_skeet/commentapi.aspx?PostID=1655908</wfw:comment><comments>http://msmvps.com/blogs/jon_skeet/archive/2008/12/05/redesigning-system-object-java-lang-object.aspx#comments</comments><description>&lt;p&gt;I&amp;#39;ve had quite a few discussions with a colleague about some failures of Java and .NET. The issue we keep coming back to is the root of the inheritance tree. There&amp;#39;s no doubt in my mind that &lt;em&gt;having&lt;/em&gt; a tree with a single top-level class is a good thing, but it&amp;#39;s grown a bit too big for its boots.&lt;/p&gt; &lt;p&gt;Pretty much everything in this post applies to both .NET and Java, sometimes with a few small changes. Where it might be unclear, I&amp;#39;ll point out the changes explicitly - otherwise I&amp;#39;ll just use the .NET terminology.&lt;/p&gt; &lt;h3&gt;What&amp;#39;s in &lt;a href="http://msdn.microsoft.com/en-us/library/system.object.aspx"&gt;System.Object&lt;/a&gt;?&lt;/h3&gt; &lt;p&gt;Before we work out what we might be able to change, let&amp;#39;s look at what we&amp;#39;ve got. I&amp;#39;m only talking about instance methods. At the moment:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;A &lt;a href="http://msdn.microsoft.com/en-us/library/system.object.object.aspx"&gt;parameterless constructor&lt;/a&gt;  &lt;li&gt;A &lt;a href="http://msdn.microsoft.com/en-us/library/system.object.finalize.aspx"&gt;finalizer&lt;/a&gt;  &lt;li&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/system.object.gettype.aspx"&gt;GetType()&lt;/a&gt;  &lt;li&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/system.object.gethashcode.aspx"&gt;GetHashCode()&lt;/a&gt;  &lt;li&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/system.object.equals.aspx"&gt;Equals(Object)&lt;/a&gt;  &lt;li&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/system.object.tostring.aspx"&gt;ToString()&lt;/a&gt;  &lt;li&gt;(&lt;a href="http://msdn.microsoft.com/en-us/library/system.threading.monitor.wait.aspx"&gt;Monitor.Wait&lt;/a&gt;)  &lt;li&gt;(&lt;a href="http://msdn.microsoft.com/en-us/library/system.threading.monitor.pulse.aspx"&gt;Monitor.Pulse&lt;/a&gt;)  &lt;li&gt;(&lt;a href="http://msdn.microsoft.com/en-us/library/system.threading.monitor.pulseall.aspx"&gt;Monitor.PulseAll&lt;/a&gt;)  &lt;li&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/system.object.memberwiseclone.aspx"&gt;MemberwiseClone&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt; &lt;h3&gt;Life-cycle and type identity&lt;/h3&gt; &lt;p&gt;There are three members which I believe really need to be left alone.&lt;/p&gt; &lt;p&gt;We need a parameterless constructor because (at least with the current system of chaining constructors to each other) we have to have &lt;em&gt;some&lt;/em&gt; constructor, and I can&amp;#39;t imagine what parameter we might want to give it. I certainly find it hard to believe there&amp;#39;s a particular piece of state which really deserves to be a part of &lt;em&gt;every&lt;/em&gt; object but which we&amp;#39;re currently missing.&lt;/p&gt; &lt;p&gt;I really don&amp;#39;t care that much about finalizers. Should the finalizer be part of Object itself, or should it just get handled automatically by the CLR if and only if it&amp;#39;s defined somewhere in the inheritance chain? Frankly, who cares. No doubt it makes a big difference to the implementation somewhere, but that&amp;#39;s not my problem. All I care about when it comes to finalizers is that when I have to write them it&amp;#39;s as easy as possible to do it properly, and that I don&amp;#39;t have to write them very often in the first place. (With &lt;a href="http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.safehandle.aspx"&gt;SafeHandle&lt;/a&gt;, it should be a pretty rare occurrence in .NET, even when you&amp;#39;re dealing directly with unmanaged resources.)&lt;/p&gt; &lt;p&gt;GetType() or (getClass() in Java) is pretty important. I can&amp;#39;t see any particular alternative to having this within Object, unless you make it a static method somewhere else with an Object parameter. In fact, that would have the advantage of freeing up the name for use within your own classes. The functionality is sufficiently important (and really does apply to every object) that I think it&amp;#39;s worth keeping.&lt;/p&gt; &lt;h3&gt;Comparison methods&lt;/h3&gt; &lt;p&gt;Okay, time to get controversial. I don&amp;#39;t think every object should have to be able to compare itself with another object. Of course, most types don&amp;#39;t really support this anyway - we just end up with reference equality by default.&lt;/p&gt; &lt;p&gt;The trouble with comparisons is that everyone&amp;#39;s got a different idea of what makes something equal. There are some types where it really is obvious - there&amp;#39;s only one natural comparison. Integers spring to mind. There are other types which have multiple natural equality comparisons - floating point numbers (exact, within an absolute epsilon, and within a relative epsilon) and strings (ordinal, culture sensitive and/or case sensitive) are examples of this. Then there are composite types where you may or may not care about certain aspects - when comparing URLs, do I care about case? Do I care about fragments? For http, if the port number is explicitly specified as 80, is that different to a URL which is still http but leaves the port number implicit?&lt;/p&gt; &lt;p&gt;.NET represents these reasonably well already, with the &lt;a href="http://msdn.microsoft.com/en-us/library/ms131187.aspx"&gt;IEquatable&amp;lt;T&amp;gt;&lt;/a&gt; interface saying &amp;quot;I know how to compare myself with an instance of type T, and how to produce a hashcode for myself&amp;quot; and &lt;a href="http://msdn.microsoft.com/en-us/library/ms132151.aspx"&gt;IEqualityComparer&amp;lt;T&amp;gt;&lt;/a&gt; interface saying &amp;quot;I know how to compare two instances of T, and how to produce a hashcode for one instance of T.&amp;quot; Now suppose we didn&amp;#39;t have the (nongeneric!) Equals() method and GetHashCode() in System.Object. Any type which had a natural equality comparison would still let you compare it for equality by implementing IEquatable&amp;lt;T&amp;gt;.Equals - but anything else would either force you to use reference equality or an implementation of IEqualityComparer&amp;lt;T&amp;gt;.&lt;/p&gt; &lt;p&gt;Some of the principle consumers of equality comparisons are collections - particularly dictionaries (which is why it&amp;#39;s so important that the interfaces should include hashcode generation). With the current way that .NET generics work, it would be tricky to have a constraint on a &lt;em&gt;constructor&lt;/em&gt; such that if you only specified the types, it would only work if the key type implemented IEquatable&amp;lt;T&amp;gt;, but it&amp;#39;s easy enough to do with static methods (on a non-generic type). Alternatively you could specify any type and an appropriate IEqualityComparer&amp;lt;T&amp;gt; to use for the keys. We&amp;#39;d need an IdentityComparer&amp;lt;T&amp;gt; to work just with references (and provide the equivalent functionaliy to Object.GetHashCode) but that&amp;#39;s not hard - and it would be &lt;em&gt;absolutely&lt;/em&gt; obvious what the comparison was when you built the dictionary.&lt;/p&gt; &lt;h3&gt;Monitors and threading&lt;/h3&gt; &lt;p&gt;This is possibly my biggest gripe. The fact that every object has a monitor associated with it was a mistake in Java, and was unfortunately copied in .NET. This promotes the bad practice of locking on &amp;quot;this&amp;quot; and on types - both of which are typically publicly accessible references. I believe that unless a reference is exposed explicitly for the purpose of locking (like &lt;a href="http://msdn.microsoft.com/en-us/library/system.collections.icollection.syncroot.aspx"&gt;ICollection.SyncRoot&lt;/a&gt;) then you should avoid locking on any reference which other code knows about. I typically have a private read-only variable for locking purposes. If you&amp;#39;re following these guidelines, it makes no sense to be able to lock on absolutely any reference - it would be better to make the Monitor class instantiable, and make Wait/Pulse/PulseAll instance members. (In Java this would mean creating a new class and moving Object.wait/notify/notifyAll members to that class.)&lt;/p&gt; &lt;p&gt;This would lead to cleaner, more readable code in my view. I&amp;#39;d also do away with the &amp;quot;lock&amp;quot; statement in C#, making Monitor.Enter return a token implementing IDisposable - so &amp;quot;using&amp;quot; statements would replace locks, freeing up a keyword &lt;em&gt;and&lt;/em&gt; giving the flexibility of having multiple overloads of Monitor.Enter. Arguably if one were redesigning all of this anyway, it would be worth looking at whether or not monitors should really be reentrant. Any time you &lt;em&gt;use&lt;/em&gt; lock reentrancy, you&amp;#39;re probably not thinking hard enough about the design. Now there&amp;#39;s a nice overgeneralisation with which to end this section...&lt;/p&gt; &lt;h3&gt;String representations&lt;/h3&gt; &lt;p&gt;This is an interesting one. I&amp;#39;m genuinely on the fence here. I find ToString() (and the fact that it&amp;#39;s called implicitly in many circumstances) hugely useful, but it feels like it&amp;#39;s attempting to satisfy three different goals:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Giving a developer-readable representation when logging and debugging&lt;/li&gt; &lt;li&gt;Giving a user-readable representation as part of a formatted message in a UI&lt;/li&gt; &lt;li&gt;Giving a machine-readable format (although this is relatively rare for anything other than numeric types)&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;It&amp;#39;s interesting to note that Java and .NET differ as to which of these to use for numbers - Java plumps for &amp;quot;machine-readable&amp;quot; and .NET goes for &amp;quot;human-readable in the current thread&amp;#39;s culture&amp;quot;. Of course it&amp;#39;s clearer to explicitly specify the culture on both platforms.&lt;/p&gt; &lt;p&gt;The trouble is that &lt;em&gt;very&lt;/em&gt; often, it&amp;#39;s not immediately clear which of these has been implemented. This leads to guidelines such as &amp;quot;don&amp;#39;t use ToString() other than for logging&amp;quot; on the grounds that at least if it&amp;#39;s implemented inappropriately, it&amp;#39;ll only be a log file which ends up with difficult-to-understand data.&lt;/p&gt; &lt;p&gt;Should this usage be explicitly stated - perhaps even codified in the name: &amp;quot;ToDebugString&amp;quot; or something similar? I will leave this for smarter minds to think about, but I think there&amp;#39;s enough value in the method to make it worth keeping.&lt;/p&gt; &lt;h3&gt;MemberwiseClone&lt;/h3&gt; &lt;p&gt;Again, I&amp;#39;m not sure on this one. It would perhaps be better as a static (generic!) method somewhere in a class whose name indicated &amp;quot;this is for sneaky runtime stuff&amp;quot;. After all, it constructs a new object without calling a constructor, and other funkiness. I&amp;#39;m less bothered by this than the other items though.&lt;/p&gt; &lt;h3&gt;Conclusion&lt;/h3&gt; &lt;p&gt;To summarise, in an ideal world:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Equals and GetHashCode would disappear from Object. Types would have to explicitly say that they could be compared&lt;/li&gt; &lt;li&gt;Wait/Pulse/PulseAll would become instance methods in Monitor, which would be instantiated every time you want a lock.&lt;/li&gt; &lt;li&gt;ToString &lt;em&gt;might&lt;/em&gt; be renamed to give clearer usage guidance.&lt;/li&gt; &lt;li&gt;MemberwiseClone &lt;em&gt;might&lt;/em&gt; be moved to a different class.&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;Obviously it&amp;#39;s far too late for either Java or .NET to make these changes, but it&amp;#39;s always interesting to dream. Any more changes you&amp;#39;d like to see? Or violent disagreements with any of the above?&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1655908" 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/Java/default.aspx">Java</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/CSharpDevCenter/default.aspx">CSharpDevCenter</category><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/CSharpDev/default.aspx">CSharpDev</category></item><item><title>Jaffa bugs</title><link>http://msmvps.com/blogs/jon_skeet/archive/2008/11/06/jaffa-bugs.aspx</link><pubDate>Thu, 06 Nov 2008 17:15:57 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1653278</guid><dc:creator>skeet</dc:creator><slash:comments>4</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/jon_skeet/rsscomments.aspx?PostID=1653278</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/jon_skeet/commentapi.aspx?PostID=1653278</wfw:comment><comments>http://msmvps.com/blogs/jon_skeet/archive/2008/11/06/jaffa-bugs.aspx#comments</comments><description>&lt;p&gt;Currently I&amp;#39;m working on a problem found by one of our testers. Unfortunately, it&amp;#39;s hard to reproduce. Inspired by the fact that yesterday our micro-kitchen had jaffa cakes in, I propose that if we&amp;#39;re going to be frustrated by bugs like this, we might as well at least mock them.&lt;/p&gt; &lt;p&gt;I propose that we call them jaffa bugs, and will work hard to promote this jargon until it takes over the world. Insert evil laugh here.&lt;/p&gt; &lt;p&gt;(Just in case the etymology here isn&amp;#39;t clear, see the &lt;a href="http://en.wikipedia.org/wiki/Only_Fools_and_Horses"&gt;Wikipedia &amp;quot;Only Fools and Horses&amp;quot; entry&lt;/a&gt;.)&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1653278" 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/Wacky+Ideas/default.aspx">Wacky Ideas</category></item><item><title>C# 4.0: dynamic&lt;T&gt; ?</title><link>http://msmvps.com/blogs/jon_skeet/archive/2008/10/30/c-4-0-dynamic-lt-t-gt.aspx</link><pubDate>Thu, 30 Oct 2008 22:04:10 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1652571</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=1652571</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/jon_skeet/commentapi.aspx?PostID=1652571</wfw:comment><comments>http://msmvps.com/blogs/jon_skeet/archive/2008/10/30/c-4-0-dynamic-lt-t-gt.aspx#comments</comments><description>&lt;p&gt;I&amp;#39;ve not played with the VS2010 CTP much yet, and I&amp;#39;ve only looked briefly at the documentation and blogs about the new C# 4.0 &lt;code&gt;dynamic&lt;/code&gt; type, but a thought occurred to me: why not have the option of making it generic as a way of saying &amp;quot;I will dynamically support this set of operations&amp;quot;?&lt;/p&gt; &lt;p&gt;As an example of what I mean, suppose you have an interface &lt;code&gt;IMessageRouter&lt;/code&gt; like this:&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; IMessageRouter&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="ValueType"&gt;void&lt;/span&gt; Send(&lt;span class="ReferenceType"&gt;string&lt;/span&gt; message, &lt;span class="ReferenceType"&gt;string&lt;/span&gt; destination);&lt;br /&gt;} &lt;/div&gt; &lt;p&gt;(This is an arbitrary example, by the way. The idea isn&amp;#39;t specifically more suitable for message routing than anything else.)&lt;/p&gt; &lt;p&gt;I may have various implementations, written in various languages (or COM) which support the &lt;code&gt;Send&lt;/code&gt; method with those parameters. Some of those implementations actually implement &lt;code&gt;IMessageRouter&lt;/code&gt; but some don&amp;#39;t. I&amp;#39;d like to be able to do the following:&lt;/p&gt; &lt;div class="code"&gt;dynamic&amp;lt;IMessageRouter&amp;gt; router = GetRouter();&lt;br /&gt;&lt;br /&gt;&lt;span class="InlineComment"&gt;// This is fine (but still invoked dynamically)&lt;/span&gt;&lt;br /&gt;router.Send(&lt;span class="String"&gt;&amp;quot;message&amp;quot;&lt;/span&gt;, &lt;span class="String"&gt;&amp;quot;skeet@pobox.com&amp;quot;&lt;/span&gt;);&lt;br /&gt;&lt;span class="InlineComment"&gt;// Compilation error: no such overload&lt;/span&gt;&lt;br /&gt;router.Send(&lt;span class="String"&gt;&amp;quot;message&amp;quot;&lt;/span&gt;, &lt;span class="String"&gt;&amp;quot;skeet@pobox.com&amp;quot;&lt;/span&gt;, 20); &lt;/div&gt; &lt;p&gt;Intellisense would work, and we&amp;#39;d still have some of the benefits of static typing but without the implementations having to know about your interface. Of course, it would be quite easy to create an implementation of the interface which did exactly this - but now imagine that instead of &lt;code&gt;IMessageRouter&lt;/code&gt; we had &lt;code&gt;MessageRouter&lt;/code&gt; - a concrete class. In this case the compiler would still restrict the caller to the public API of the class, but it wouldn&amp;#39;t have to be the real class. No checking would be performed by the compiler that your dynamic type &lt;i&gt;actually&lt;/i&gt; supported the operations - given that we&amp;#39;re talking about dynamic invocation, that would be impossible to do. It would instead be an &amp;quot;opt-in&amp;quot; restriction the client places on themselves. It could also potentially help with performance - if the binding involved realised that the &lt;i&gt;actual&lt;/i&gt; type of the dynamic object natively implemented the interface or was/derived from the class, then no real dynamic calls need be made; just route all directly. &lt;/p&gt; &lt;p&gt;This may all sound a bit fuzzy - I&amp;#39;m extremely sleepy, to be honest - but I think it&amp;#39;s a potentially interesting idea. Thoughts? &lt;/p&gt; &lt;h2&gt;Update&lt;/h2&gt;Apparently this post wasn&amp;#39;t as clear as it might be. I&amp;#39;m quite happy to keep the currently proposed dynamic type idea &lt;em&gt;as well&lt;/em&gt; - I&amp;#39;d like this as an &lt;em&gt;additional&lt;/em&gt; way of using dynamic objects.&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1652571" 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/C_2300_+4/default.aspx">C# 4</category><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/CSharpDevCenter/default.aspx">CSharpDevCenter</category><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/CSharpDev/default.aspx">CSharpDev</category></item><item><title>I'm Sorry, I Haven't a Cluestick</title><link>http://msmvps.com/blogs/jon_skeet/archive/2008/06/20/i-m-sorry-i-haven-t-a-cluestick.aspx</link><pubDate>Fri, 20 Jun 2008 16:22:39 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1636115</guid><dc:creator>skeet</dc:creator><slash:comments>4</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/jon_skeet/rsscomments.aspx?PostID=1636115</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/jon_skeet/commentapi.aspx?PostID=1636115</wfw:comment><comments>http://msmvps.com/blogs/jon_skeet/archive/2008/06/20/i-m-sorry-i-haven-t-a-cluestick.aspx#comments</comments><description>&lt;p&gt;Unless you&amp;#39;ve listened to &lt;a href="http://en.wikipedia.org/wiki/I%27m_Sorry_I_Haven%27t_a_Clue"&gt;I&amp;#39;m Sorry, I Haven&amp;#39;t a Clue&lt;/a&gt;, the BBC Radio 4 &amp;quot;antidote to panel games&amp;quot; which was chaired by the recently departed (and much missed) &lt;a href="http://en.wikipedia.org/wiki/Humphrey_Lyttelton"&gt;Humphrey Lyttelton&lt;/a&gt;, this post may not make a lot of sense to you. That&amp;#39;s not intended to guarantee that it&amp;#39;ll make any sense to you even if you &lt;em&gt;have&lt;/em&gt; listened to it, mind you.&lt;/p&gt; &lt;p&gt;ISIHAC was full of very silly improvisation games. I was listening to an episode last night, and thought a developer version could be equally silly. Games played might include the following: (links show the Wikipedia description of the original)&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href="http://en.wikipedia.org/wiki/One_Song_to_the_Tune_of_Another"&gt;One language to the API of another&lt;/a&gt;: Not so much a joke as a strategy now at both Microsoft and Sun, but I&amp;#39;m sure it could be taken to extremes. Ever fancied using the ZX Spectrum BASIC functions from C#? How about SmallTalk from Java?  &lt;li&gt;&lt;a href="http://en.wikipedia.org/wiki/Mornington_Crescent_%28game%29"&gt;Singleton Crescent&lt;/a&gt;: Players name design patterns, seemingly at random to the unenlightened observer, until one of them declares &amp;quot;Singleton&amp;quot;. Multiple variations exist, such as Gamma&amp;#39;s Folly: &amp;quot;After a diagonal move ending on a creational pattern, a behavioural pattern is &lt;em&gt;not&lt;/em&gt; permitted.&amp;quot;  &lt;li&gt;&lt;a href="http://en.wikipedia.org/wiki/Cheddar_Gorge_%28game%29#Cheddar_Gorge"&gt;Fluent Gorge&lt;/a&gt;: Players start with a single method call and add additional expressions. The player who inadvertently completes the statement is the loser. This game is already played at lunchtime in many ISVs, some of whom accidentally check in the tortuous code afterwards.  &lt;li&gt;&lt;a href="http://en.wikipedia.org/wiki/Cheddar_Gorge_%28game%29#Pick-up_Song"&gt;Pick-up algorithm&lt;/a&gt;: A player begins copying code out of a book, which is then removed after a few lines. They then have to continue coding as accurately as possible until the book is brought back. Points are awarded if they&amp;#39;re within a gnat&amp;#39;s semi-colon of the original. Bonus points used to be awarded if the resulting code had fewer bugs in than the printed original, but this practice has recently been discontinued as being a near-trivial way of achieving a high score.  &lt;li&gt;&lt;a href="http://en.wikipedia.org/wiki/Cheddar_Gorge_%28game%29#Call_My_Bluff"&gt;Call my bluff&lt;/a&gt;: One player is given a single-line project goal, and then several sets of requirements purporting to support that goal. The player has to guess which set of requirements is the real one for the project. The twist is that none of the sets of requirements is even slightly realistic. Again, this game is in widespread use, played by Business Analysts on unsuspecting developers.&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;Right, that&amp;#39;s more than enough silliness. Something more serious next time, I promise.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1636115" 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/Wacky+Ideas/default.aspx">Wacky Ideas</category></item><item><title>Mandelbrot revisited - benchmark edition</title><link>http://msmvps.com/blogs/jon_skeet/archive/2008/05/18/mandelbrot-revisited-benchmark-edition.aspx</link><pubDate>Sun, 18 May 2008 21:44:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1624136</guid><dc:creator>skeet</dc:creator><slash:comments>11</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/jon_skeet/rsscomments.aspx?PostID=1624136</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/jon_skeet/commentapi.aspx?PostID=1624136</wfw:comment><comments>http://msmvps.com/blogs/jon_skeet/archive/2008/05/18/mandelbrot-revisited-benchmark-edition.aspx#comments</comments><description>&lt;p&gt;I&amp;#39;ve had fun with the Mandelbrot set in this blog before, using it as an example of an embarrassingly parallelisable problem and demonstrating Parallel LINQ with it. &lt;/p&gt; &lt;p&gt;This morning, over breakfast, I described the problem to &lt;a href="http://www.brunschen.com/christian/"&gt;Christian Brunschen&lt;/a&gt;, a colleague of mine who has some parallelisation experience through &lt;a href="http://www.brunschen.com/christian/OdinMP/"&gt;implementing OpenMP in a portable manner&lt;/a&gt;. He immediately suggested a few possible changes to the way that I&amp;#39;ve approached things. Given the number of different attempts I&amp;#39;ve now had, I thought it would make sense to write a litte benchmarking app which could easily be expanded as further implementations were considered. The benchmark is &lt;a href="http://pobox.com/%7Eskeet/csharp/blogfiles/MandelbrotBenchmark.zip"&gt;available for download&lt;/a&gt; so you can play around with it yourself. (As is often the case with this kind of thing, it&amp;#39;s not the nicest code in the world for various reasons - the duplication of the sequence generation method, for example... Please don&amp;#39;t use it as a tutorial on actual coding and organisation.)&lt;/p&gt; &lt;h3&gt;Benchmark implementation details&lt;/h3&gt; &lt;p&gt;The benchmark allows you to vary the size of the generated image and the maximum number of iterations per point. The images can be displayed after the test run, but only the time taken to populate a byte array is recorded. The byte arrays are all allocated before any tests are run, and the garbage collector is invoked (as far as it can be) between tests. The images themselves are only generated after the tests have all completed. Each implementation is given a tiny &amp;quot;dummy run&amp;quot; (creating an image 10 pixels across, with a maximum of 2 iterations per point) first to hopefully remove JITting from the benchmarking times. I won&amp;#39;t pretend that this puts everything on a completely level playing field (benchmarking is hard) but hopefully it&amp;#39;s a good start. We check the similarity between the results of each test and the first one - in some cases they could be &amp;quot;nearly all the same&amp;quot; without there being a bug, due to the subtleties of floating point operations and inlining.&lt;/p&gt; &lt;p&gt;The base class that all the generators use takes care of working out the height from the width, remembering the various configuration options, allocating the array, and also providing a simple imperative method to obtain the value of a single point, without using anything fancy. &lt;/p&gt; &lt;p&gt;I originally wanted to put the whole thing in a nice UI, but after wasting nearly an hour trying to get WPF to behave, I decided to go for a simple console app. One day I really must learn how to write GUIs quickly... &lt;/p&gt; &lt;p&gt;Okay, enough introduction - let&amp;#39;s look at the implementations we&amp;#39;re testing, and then the results. The idea is to get a look at how a number of areas influence the results, as well as seeing some nifty ways of expressing things functionally.&lt;/p&gt; &lt;h4&gt;SingleThreadImperativeSimple&lt;/h4&gt; &lt;p&gt;This is the most trivial code you could write, basically. As the base class provides the calculation method, we just go through each row and column, work out the value, and store it in the array. The only attempt at optimisation is keeping the &amp;quot;current index&amp;quot; into the array rather than calculating it for every point.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div class="code"&gt;&lt;span class="Modifier"&gt;public&lt;/span&gt;&amp;nbsp;&lt;span class="Modifier"&gt;override&lt;/span&gt;&amp;nbsp;&lt;span class="ValueType"&gt;void&lt;/span&gt; Generate()&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="ValueType"&gt;int&lt;/span&gt; index = 0;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="Statement"&gt;for&lt;/span&gt; (&lt;span class="ValueType"&gt;int&lt;/span&gt; row = 0; row &amp;lt; Height; row++)&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;for&lt;/span&gt; (&lt;span class="ValueType"&gt;int&lt;/span&gt; col = 0; col &amp;lt; Width; col++)&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; Data[index++] = ComputeMandelbrotIndex(row, col);&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;&amp;nbsp;&lt;/p&gt; &lt;p&gt;where &lt;code&gt;ComplexMandelbrotIndex&lt;/code&gt; is in the base class:&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div class="code"&gt;&lt;span class="Modifier"&gt;protected&lt;/span&gt;&amp;nbsp;&lt;span class="ValueType"&gt;byte&lt;/span&gt; ComputeMandelbrotIndex(&lt;span class="ValueType"&gt;int&lt;/span&gt; row, &lt;span class="ValueType"&gt;int&lt;/span&gt; col)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="ValueType"&gt;double&lt;/span&gt; x = (col * SampleWidth) / Width + OffsetX;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="ValueType"&gt;double&lt;/span&gt; y = (row * SampleHeight) / Height + OffsetY;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="ValueType"&gt;double&lt;/span&gt; y0 = y;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="ValueType"&gt;double&lt;/span&gt; x0 = x;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="Statement"&gt;for&lt;/span&gt; (&lt;span class="ValueType"&gt;int&lt;/span&gt; i = 0; i &amp;lt; MaxIterations; i++)&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;if&lt;/span&gt; (x * x + y * y &amp;gt;= 4)&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;return&lt;/span&gt; (&lt;span class="ValueType"&gt;byte&lt;/span&gt;)((i % 255) + 1);&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; &lt;span class="ValueType"&gt;double&lt;/span&gt; xtemp = x * x - y * y + x0;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; y = 2 * x * y + y0;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; x = xtemp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="Statement"&gt;return&lt;/span&gt; 0;&lt;br /&gt;} &lt;/div&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;h4&gt;SingleThreadImperativeInline&lt;/h4&gt; &lt;p&gt;This is largely the same code as SingleThreadImperativeSimple, but with everything inlined. Within the main body, there&amp;#39;s no access to anything other than local variables, and no method calls. One further optimisation is available: points which will have a value of 0 aren&amp;#39;t stored (we assume we&amp;#39;ll always start with a cleared array). &lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div class="code"&gt;&lt;span class="Modifier"&gt;public&lt;/span&gt;&amp;nbsp;&lt;span class="Modifier"&gt;override&lt;/span&gt;&amp;nbsp;&lt;span class="ValueType"&gt;void&lt;/span&gt; Generate()&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="ValueType"&gt;int&lt;/span&gt; width = Width;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="ValueType"&gt;int&lt;/span&gt; height = Height;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="ValueType"&gt;int&lt;/span&gt; maxIterations = MaxIterations;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="ValueType"&gt;int&lt;/span&gt; index = 0;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="ValueType"&gt;byte&lt;/span&gt;[] data = Data;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="Statement"&gt;for&lt;/span&gt; (&lt;span class="ValueType"&gt;int&lt;/span&gt; row = 0; row &amp;lt; height; row++)&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;for&lt;/span&gt; (&lt;span class="ValueType"&gt;int&lt;/span&gt; col = 0; col &amp;lt; width; col++)&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="ValueType"&gt;double&lt;/span&gt; x = (col * SampleWidth) / width + OffsetX;&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="ValueType"&gt;double&lt;/span&gt; y = (row * SampleHeight) / height + OffsetY;&lt;br /&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; &lt;span class="ValueType"&gt;double&lt;/span&gt; y0 = y;&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="ValueType"&gt;double&lt;/span&gt; x0 = x;&lt;br /&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; &lt;span class="Statement"&gt;for&lt;/span&gt; (&lt;span class="ValueType"&gt;int&lt;/span&gt; i = 0; i &amp;lt; maxIterations; i++)&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="Statement"&gt;if&lt;/span&gt; (x * x + y * y &amp;gt;= 4)&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; data[index] = (&lt;span class="ValueType"&gt;byte&lt;/span&gt;)((i % 255) + 1);&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; &lt;span class="Statement"&gt;break&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; }&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;double&lt;/span&gt; xtemp = x * x - y * y + x0;&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; y = 2 * x * y + y0;&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; x = xtemp;&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; &lt;span class="InlineComment"&gt;// Leave data[index] = 0 by default&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; index++;&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;&amp;nbsp;&lt;/p&gt; &lt;h4&gt;MultiThreadUpFrontSplitImperative&lt;/h4&gt; &lt;p&gt;This should be pretty efficient - work out how many cores we&amp;#39;ve got, split the work equally between them (as chunks of rows, which helps in terms of locality and just incrementing an index in the byte array each time), and then run. Wait until all the threads have finished, and we&amp;#39;re done. Shouldn&amp;#39;t be a lot of context switching required normally, and no synchronization is required. However, if some cores are busy with another process, we&amp;#39;ll end up context switching for no gain. &lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div class="code"&gt;&lt;span class="Modifier"&gt;public&lt;/span&gt;&amp;nbsp;&lt;span class="Modifier"&gt;override&lt;/span&gt;&amp;nbsp;&lt;span class="ValueType"&gt;void&lt;/span&gt; Generate()&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="ValueType"&gt;int&lt;/span&gt; cores = Environment.ProcessorCount;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="ValueType"&gt;int&lt;/span&gt; rowsPerCore = Height / cores;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; List&amp;lt;Thread&amp;gt; threads = &lt;span class="Keyword"&gt;new&lt;/span&gt; List&amp;lt;Thread&amp;gt;();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="Statement"&gt;for&lt;/span&gt; (&lt;span class="ValueType"&gt;int&lt;/span&gt; i = 0; i &amp;lt; cores; i++)&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="ValueType"&gt;int&lt;/span&gt; firstRow = rowsPerCore * i;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="ValueType"&gt;int&lt;/span&gt; rowsToCompute = rowsPerCore;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="Statement"&gt;if&lt;/span&gt; (i == cores - 1)&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; rowsToCompute = Height-(rowsPerCore*(cores-1));&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; Thread thread = &lt;span class="Keyword"&gt;new&lt;/span&gt; Thread(() =&amp;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; {&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;int&lt;/span&gt; index = firstRow * Width;&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;for&lt;/span&gt; (&lt;span class="ValueType"&gt;int&lt;/span&gt; row = firstRow; row &amp;lt; firstRow + rowsToCompute; row++)&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; &lt;span class="Statement"&gt;for&lt;/span&gt; (&lt;span class="ValueType"&gt;int&lt;/span&gt; col = 0; col &amp;lt; Width; col++)&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; {&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;&amp;nbsp;&amp;nbsp; Data[index++] = ComputeMandelbrotIndex(row, col);&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; }&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; });&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; thread.Start();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; threads.Add(thread);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; threads.ForEach(thread =&amp;gt; thread.Join());&lt;br /&gt;} &lt;/div&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;h4&gt;MultiThreadRowFetching&lt;/h4&gt; &lt;p&gt;Again, we use a fixed number of threads - but this time we start off with a queue of work - one task per row. The queue has to be synchronized every time we use it, and we also have to check whether or not it&amp;#39;s empty. Plenty of scope for lock contention here, particularly as the number of cores increases. &lt;/p&gt; 
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div class="code"&gt;
&lt;span class="Modifier"&gt;public&lt;/span&gt;&amp;nbsp;&lt;span class="Modifier"&gt;override&lt;/span&gt;&amp;nbsp;&lt;span class="ValueType"&gt;void&lt;/span&gt;&amp;nbsp;Generate()&lt;br /&gt;
{&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Queue&amp;lt;&lt;span class="ValueType"&gt;int&lt;/span&gt;&amp;gt;&amp;nbsp;rowsLeft&amp;nbsp;=&amp;nbsp;&lt;span class="Keyword"&gt;new&lt;/span&gt;&amp;nbsp;Queue&amp;lt;&lt;span class="ValueType"&gt;int&lt;/span&gt;&amp;gt;(Enumerable.Range(0,&amp;nbsp;Height));&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;List&amp;lt;Thread&amp;gt;&amp;nbsp;threads&amp;nbsp;=&amp;nbsp;&lt;span class="Keyword"&gt;new&lt;/span&gt;&amp;nbsp;List&amp;lt;Thread&amp;gt;();&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="Statement"&gt;for&lt;/span&gt;&amp;nbsp;(&lt;span class="ValueType"&gt;int&lt;/span&gt;&amp;nbsp;i&amp;nbsp;=&amp;nbsp;0;&amp;nbsp;i&amp;nbsp;&amp;lt;&amp;nbsp;Environment.ProcessorCount;&amp;nbsp;i++)&lt;br /&gt;
&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;Thread&amp;nbsp;thread&amp;nbsp;=&amp;nbsp;&lt;span class="Keyword"&gt;new&lt;/span&gt;&amp;nbsp;Thread(()&amp;nbsp;=&amp;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;{&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;&lt;span class="Statement"&gt;while&lt;/span&gt;&amp;nbsp;(&lt;span class="Keyword"&gt;true&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;{&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;&lt;span class="ValueType"&gt;int&lt;/span&gt;&amp;nbsp;row;&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;&lt;span class="Statement"&gt;lock&lt;/span&gt;&amp;nbsp;(rowsLeft)&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;{&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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="Statement"&gt;if&lt;/span&gt;&amp;nbsp;(rowsLeft.Count&amp;nbsp;==&amp;nbsp;0)&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;&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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="Statement"&gt;break&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;&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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;row&amp;nbsp;=&amp;nbsp;rowsLeft.Dequeue();&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;}&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;&lt;span class="ValueType"&gt;int&lt;/span&gt;&amp;nbsp;index&amp;nbsp;=&amp;nbsp;row&amp;nbsp;*&amp;nbsp;Width;&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;&lt;span class="Statement"&gt;for&lt;/span&gt;&amp;nbsp;(&lt;span class="ValueType"&gt;int&lt;/span&gt;&amp;nbsp;col&amp;nbsp;=&amp;nbsp;0;&amp;nbsp;col&amp;nbsp;&amp;lt;&amp;nbsp;Width;&amp;nbsp;col++)&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;{&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;&amp;nbsp;&amp;nbsp;&amp;nbsp;Data[index++]&amp;nbsp;=&amp;nbsp;ComputeMandelbrotIndex(row,&amp;nbsp;col);&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;}&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;}&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;});&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;thread.Start();&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;threads.Add(thread);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;threads.ForEach(thread&amp;nbsp;=&amp;gt;&amp;nbsp;thread.Join());&lt;br /&gt;
}
&lt;/div&gt;

&lt;h4&gt;SingleThreadLinqSimple&lt;/h4&gt; &lt;p&gt;This is the &lt;a href="http://msmvps.com/blogs/jon.skeet/archive/2007/10/03/linq-to-silliness-generating-a-mandelbrot-with-parallel-potential.aspx"&gt;first version&lt;/a&gt; of Mandelbrot generation I wrote since thinking of using LINQ, tweaked a litte to dump the output into an existing array instead of creating a new one. It&amp;#39;s essentially the same as SingleThreadImperativeSimple but with the &lt;code&gt;for&lt;/code&gt; loops replaced with a query expression. &lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div class="code"&gt;&lt;span class="Modifier"&gt;public&lt;/span&gt;&amp;nbsp;&lt;span class="Modifier"&gt;override&lt;/span&gt;&amp;nbsp;&lt;span class="ValueType"&gt;void&lt;/span&gt; Generate()&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="Linq"&gt;var&lt;/span&gt; query = &lt;span class="Linq"&gt;from&lt;/span&gt; row &lt;span class="Statement"&gt;in&lt;/span&gt; Enumerable.Range(0, Height)&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="Linq"&gt;from&lt;/span&gt; col &lt;span class="Statement"&gt;in&lt;/span&gt; Enumerable.Range(0, Width)&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="Linq"&gt;select&lt;/span&gt; ComputeMandelbrotIndex(row, col);&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="ValueType"&gt;int&lt;/span&gt; index=0;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="Statement"&gt;foreach&lt;/span&gt; (&lt;span class="ValueType"&gt;byte&lt;/span&gt; b &lt;span class="Statement"&gt;in&lt;/span&gt; query)&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; Data[index++] = b;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;} &lt;/div&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;h4&gt;ParallelLinqRowByRowWithCopy&lt;/h4&gt; &lt;p&gt;My first attempt using Parallel LINQ was &lt;a href="http://msmvps.com/blogs/jon.skeet/archive/2007/12/04/a-cautionary-parallel-tale-ordering-isn-t-simple.aspx"&gt;somewhat disastrous&lt;/a&gt; due to the nature of PLINQ&amp;#39;s ordering. To combat this effect, I initially computed a row at a time, then copying each row into place afterwards: &lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div class="code"&gt;&lt;span class="Modifier"&gt;private&lt;/span&gt;&amp;nbsp;&lt;span class="ValueType"&gt;byte&lt;/span&gt;[] ComputeMandelbrotRow(&lt;span class="ValueType"&gt;int&lt;/span&gt; row)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="ValueType"&gt;byte&lt;/span&gt;[] ret = &lt;span class="Keyword"&gt;new&lt;/span&gt;&amp;nbsp;&lt;span class="ValueType"&gt;byte&lt;/span&gt;[Width];&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="Statement"&gt;for&lt;/span&gt; (&lt;span class="ValueType"&gt;int&lt;/span&gt; col = 0; col &amp;lt; Width; col++)&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; ret[col] = ComputeMandelbrotIndex(row, col);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="Statement"&gt;return&lt;/span&gt; ret;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span class="Modifier"&gt;public&lt;/span&gt;&amp;nbsp;&lt;span class="Modifier"&gt;override&lt;/span&gt;&amp;nbsp;&lt;span class="ValueType"&gt;void&lt;/span&gt; Generate()&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="Linq"&gt;var&lt;/span&gt; query = &lt;span class="Linq"&gt;from&lt;/span&gt; row &lt;span class="Statement"&gt;in&lt;/span&gt; Enumerable.Range(0, Height).AsParallel(ParallelQueryOptions.PreserveOrdering)&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="Linq"&gt;select&lt;/span&gt; ComputeMandelbrotRow(row);&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="ValueType"&gt;int&lt;/span&gt; rowStart = 0;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="Statement"&gt;foreach&lt;/span&gt; (&lt;span class="ValueType"&gt;byte&lt;/span&gt;[] row &lt;span class="Statement"&gt;in&lt;/span&gt; query)&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; Array.Copy(row, 0, Data, rowStart, Width);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; rowStart += Width;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;} &lt;/div&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;h4&gt;ParallelLinqRowByRowInPlace&lt;/h4&gt; &lt;p&gt;An obvious potential improvement is to write the data to the eventual target array as we go, to avoid creating the extra array creation and copying. At this point we have less of a purely functional solution, but it&amp;#39;s interesting anyway. Note that to use this idea in a query expression we have to return &lt;i&gt;something&lt;/i&gt; even though it&amp;#39;s not useful. Likewise we have to make the query execute fully - so I use &lt;code&gt;Max()&lt;/code&gt; to ensure that all the results will be computed. (I originally tried &lt;code&gt;Count()&lt;/code&gt; but that didn&amp;#39;t work - presumably because the count of the results is known before the actual values are.) As we&amp;#39;re writing the data to the right place on each iteration, we no longer need to preserve ordering. &lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div class="code"&gt;&lt;span class="Modifier"&gt;private&lt;/span&gt;&amp;nbsp;&lt;span class="ValueType"&gt;int&lt;/span&gt; ComputeMandelbrotRow(&lt;span class="ValueType"&gt;int&lt;/span&gt; row)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="ValueType"&gt;int&lt;/span&gt; index = row * Width;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="Statement"&gt;for&lt;/span&gt; (&lt;span class="ValueType"&gt;int&lt;/span&gt; col = 0; col &amp;lt; Width; col++)&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; Data[index++] = ComputeMandelbrotIndex(row, col);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="Statement"&gt;return&lt;/span&gt; 0;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span class="Modifier"&gt;public&lt;/span&gt;&amp;nbsp;&lt;span class="Modifier"&gt;override&lt;/span&gt;&amp;nbsp;&lt;span class="ValueType"&gt;void&lt;/span&gt; Generate()&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="Linq"&gt;var&lt;/span&gt; query = &lt;span class="Linq"&gt;from&lt;/span&gt; row &lt;span class="Statement"&gt;in&lt;/span&gt; Enumerable.Range(0, Height).AsParallel()&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="Linq"&gt;select&lt;/span&gt; ComputeMandelbrotRow(row);&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; query.Max();&lt;br /&gt;} &lt;/div&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;h4&gt;ParallelLinqWithSequenceOfPoints&lt;/h4&gt; &lt;p&gt;After this initial foray into Parallel LINQ, Nicholas Palladinos suggested that I could adapt the original idea in a more elegant manner by treating the sequence of points as a single input sequence, and asking Parallel LINQ to preserve the order of that whole sequence. &lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div class="code"&gt;&lt;span class="Modifier"&gt;public&lt;/span&gt;&amp;nbsp;&lt;span class="Modifier"&gt;override&lt;/span&gt;&amp;nbsp;&lt;span class="ValueType"&gt;void&lt;/span&gt; Generate()&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="Linq"&gt;var&lt;/span&gt; points = &lt;span class="Linq"&gt;from&lt;/span&gt; row &lt;span class="Statement"&gt;in&lt;/span&gt; Enumerable.Range(0, Height)&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; &lt;span class="Linq"&gt;from&lt;/span&gt; col &lt;span class="Statement"&gt;in&lt;/span&gt; Enumerable.Range(0, Width)&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; &lt;span class="Linq"&gt;select&lt;/span&gt;&amp;nbsp;&lt;span class="Keyword"&gt;new&lt;/span&gt; { row, col };&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="Linq"&gt;var&lt;/span&gt; query = &lt;span class="Linq"&gt;from&lt;/span&gt; point &lt;span class="Statement"&gt;in&lt;/span&gt; points.AsParallel(ParallelQueryOptions.PreserveOrdering)&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="Linq"&gt;select&lt;/span&gt; ComputeMandelbrotIndex(point.row, point.col);&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="ValueType"&gt;int&lt;/span&gt; index=0;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="Statement"&gt;foreach&lt;/span&gt; (&lt;span class="ValueType"&gt;byte&lt;/span&gt; b &lt;span class="Statement"&gt;in&lt;/span&gt; query)&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; Data[index++] = b;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;} &lt;/div&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;h4&gt;SingleThreadLinqWithGenerator&lt;/h4&gt; &lt;p&gt;My next step was to try to put the &lt;a href="http://msmvps.com/blogs/jon.skeet/archive/2007/10/03/linq-to-silliness-generating-a-mandelbrot-with-parallel-potential.aspx"&gt;whole guts of the algorithm into the query expression&lt;/a&gt;, using a &lt;code&gt;Complex&lt;/code&gt; value type and a generator to create a sequence of complex numbers generated from the starting point. This is quite a natural step, as the value is computed by just considering this infinite sequence and seeing how quickly it escapes from the circle of radius 2 on the complex plane. Aside from anything else, I think it&amp;#39;s a nice example of deferred execution and streaming - the sequence really would go on forever if we didn&amp;#39;t limit it with the &lt;code&gt;Take&lt;/code&gt; and &lt;code&gt;TakeWhile&lt;/code&gt; calls, but the generator itself doesn&amp;#39;t know it&amp;#39;s being limited. This version uses a sequence of points as per ParallelLinqWithSequenceOfPoints to make it easier to parallelise later. &lt;/p&gt; &lt;p&gt;It&amp;#39;s not exactly an efficient way of doing things though - there&amp;#39;s a huge amount of calling going on from one iterator to another. I&amp;#39;m actually quite surprised that the final results aren&amp;#39;t worse than they are. &lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div class="code"&gt;&lt;span class="Modifier"&gt;public&lt;/span&gt;&amp;nbsp;&lt;span class="Modifier"&gt;override&lt;/span&gt;&amp;nbsp;&lt;span class="ValueType"&gt;void&lt;/span&gt; Generate()&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="Linq"&gt;var&lt;/span&gt; points = &lt;span class="Linq"&gt;from&lt;/span&gt; row &lt;span class="Statement"&gt;in&lt;/span&gt; Enumerable.Range(0, Height)&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; &lt;span class="Linq"&gt;from&lt;/span&gt; col &lt;span class="Statement"&gt;in&lt;/span&gt; Enumerable.Range(0, Width)&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; &lt;span class="Linq"&gt;select&lt;/span&gt;&amp;nbsp;&lt;span class="Keyword"&gt;new&lt;/span&gt; { row, col };&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="Linq"&gt;var&lt;/span&gt; query = &lt;span class="Linq"&gt;from&lt;/span&gt; point &lt;span class="Statement"&gt;in&lt;/span&gt; points&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="InlineComment"&gt;// Work out the initial complex value from the row and column&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; &lt;span class="Linq"&gt;let&lt;/span&gt; c = &lt;span class="Keyword"&gt;new&lt;/span&gt; Complex((point.col * SampleWidth) / Width + OffsetX,&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;&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; (point.row * SampleHeight) / Height + OffsetY)&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="InlineComment"&gt;// Work out the number of iterations&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; &lt;span class="Linq"&gt;select&lt;/span&gt; GenerateSequence(c, x =&amp;gt; x * x + c).TakeWhile(x =&amp;gt; x.SquareLength &amp;lt; 4)&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;&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;&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; .Take(MaxIterations)&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;&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;&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; .Count() &lt;span class="Linq"&gt;into&lt;/span&gt; count&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="InlineComment"&gt;// Map that to an appropriate byte value&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; &lt;span class="Linq"&gt;select&lt;/span&gt; (&lt;span class="ValueType"&gt;byte&lt;/span&gt;)(count == MaxIterations ? 0 : (count % 255) + 1);&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="ValueType"&gt;int&lt;/span&gt; index = 0;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="Statement"&gt;foreach&lt;/span&gt; (&lt;span class="ValueType"&gt;byte&lt;/span&gt; b &lt;span class="Statement"&gt;in&lt;/span&gt; query)&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; Data[index++] = b;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span class="Modifier"&gt;public&lt;/span&gt;&amp;nbsp;&lt;span class="Modifier"&gt;static&lt;/span&gt; IEnumerable&amp;lt;T&amp;gt; GenerateSequence&amp;lt;T&amp;gt;(T start, Func&amp;lt;T, T&amp;gt; step)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; T value = start;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="Statement"&gt;while&lt;/span&gt; (&lt;span class="Keyword"&gt;true&lt;/span&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="Statement"&gt;yield&lt;/span&gt;&amp;nbsp;&lt;span class="Statement"&gt;return&lt;/span&gt; value;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; value = step(value);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;} &lt;/div&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;h4&gt;ParallelLinqWithGenerator&lt;/h4&gt; &lt;p&gt;From the previous implementation, parallelisation is simple. &lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div class="code"&gt;&lt;span class="Modifier"&gt;public&lt;/span&gt;&amp;nbsp;&lt;span class="Modifier"&gt;override&lt;/span&gt;&amp;nbsp;&lt;span class="ValueType"&gt;void&lt;/span&gt; Generate()&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="Linq"&gt;var&lt;/span&gt; points = &lt;span class="Linq"&gt;from&lt;/span&gt; row &lt;span class="Statement"&gt;in&lt;/span&gt; Enumerable.Range(0, Height)&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; &lt;span class="Linq"&gt;from&lt;/span&gt; col &lt;span class="Statement"&gt;in&lt;/span&gt; Enumerable.Range(0, Width)&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; &lt;span class="Linq"&gt;select&lt;/span&gt;&amp;nbsp;&lt;span class="Keyword"&gt;new&lt;/span&gt; { row, col };&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="Linq"&gt;var&lt;/span&gt; query = &lt;span class="Linq"&gt;from&lt;/span&gt; point &lt;span class="Statement"&gt;in&lt;/span&gt; points.AsParallel(ParallelQueryOptions.PreserveOrdering)&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="InlineComment"&gt;// Work out the initial complex value from the row and column&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; &lt;span class="Linq"&gt;let&lt;/span&gt; c = &lt;span class="Keyword"&gt;new&lt;/span&gt; Complex((point.col * SampleWidth) / Width + OffsetX,&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;&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; (point.row * SampleHeight) / Height + OffsetY)&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="InlineComment"&gt;// Work out the number of iterations&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; &lt;span class="Linq"&gt;select&lt;/span&gt; GenerateSequence(c, x =&amp;gt; x * x + c).TakeWhile(x =&amp;gt; x.SquareLength &amp;lt; 4)&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;&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;&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; .Take(MaxIterations)&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;&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;&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; .Count() &lt;span class="Linq"&gt;into&lt;/span&gt; count&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="InlineComment"&gt;// Map that to an appropriate byte value&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; &lt;span class="Linq"&gt;select&lt;/span&gt; (&lt;span class="ValueType"&gt;byte&lt;/span&gt;)(count == MaxIterations ? 0 : (count % 255) + 1);&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="ValueType"&gt;int&lt;/span&gt; index = 0;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="Statement"&gt;foreach&lt;/span&gt; (&lt;span class="ValueType"&gt;byte&lt;/span&gt; b &lt;span class="Statement"&gt;in&lt;/span&gt; query)&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; Data[index++] = b;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;} &lt;/div&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;h4&gt;SingleThreadImperativeWithComplex&lt;/h4&gt; &lt;p&gt;Having already seen how slow the generator version was in the past, I thought it would be worth checking whether or not this was due to the use of the &lt;code&gt;Complex&lt;/code&gt; struct - so this is a version which uses that, but is otherwise just like the very first implementation (SingleThreadImperativeSimple).&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div class="code"&gt;&lt;span class="Modifier"&gt;public&lt;/span&gt;&amp;nbsp;&lt;span class="Modifier"&gt;override&lt;/span&gt;&amp;nbsp;&lt;span class="ValueType"&gt;void&lt;/span&gt; Generate()&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="ValueType"&gt;int&lt;/span&gt; index = 0;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="Statement"&gt;for&lt;/span&gt; (&lt;span class="ValueType"&gt;int&lt;/span&gt; row = 0; row &amp;lt; Height; row++)&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;for&lt;/span&gt; (&lt;span class="ValueType"&gt;int&lt;/span&gt; col = 0; col &amp;lt; Width; col++)&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; Data[index++] = ComputeMandelbrotIndexWithComplex(row, col);&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;br /&gt;&lt;br /&gt;&lt;span class="ValueType"&gt;byte&lt;/span&gt; ComputeMandelbrotIndexWithComplex(&lt;span class="ValueType"&gt;int&lt;/span&gt; row, &lt;span class="ValueType"&gt;int&lt;/span&gt; col)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="ValueType"&gt;double&lt;/span&gt; x = (col * SampleWidth) / Width + OffsetX;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="ValueType"&gt;double&lt;/span&gt; y = (row * SampleHeight) / Height + OffsetY;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Complex start = &lt;span class="Keyword"&gt;new&lt;/span&gt; Complex(x, y);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Complex current = start;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="Statement"&gt;for&lt;/span&gt; (&lt;span class="ValueType"&gt;int&lt;/span&gt; i = 0; i &amp;lt; MaxIterations; i++)&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;if&lt;/span&gt; (current.SquareLength &amp;gt;= 4)&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;return&lt;/span&gt; (&lt;span class="ValueType"&gt;byte&lt;/span&gt;)((i % 255) + 1);&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; current = current * current + start;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="Statement"&gt;return&lt;/span&gt; 0;&lt;br /&gt;} &lt;/div&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;h4&gt;UnorderedParallelLinqSimple&lt;/h4&gt; &lt;p&gt;This is where my colleague, Christian, came in. He suggested that instead of ordering the results, we just return the point as well as its value. We can then populate the array directly, regardless of the order of the results. The first version just uses an anonymous type to represent the combination:&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div class="code"&gt;&lt;span class="Modifier"&gt;public&lt;/span&gt;&amp;nbsp;&lt;span class="Modifier"&gt;override&lt;/span&gt;&amp;nbsp;&lt;span class="ValueType"&gt;void&lt;/span&gt; Generate()&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="Linq"&gt;var&lt;/span&gt; query = &lt;span class="Linq"&gt;from&lt;/span&gt; row &lt;span class="Statement"&gt;in&lt;/span&gt; Enumerable.Range(0, Height).AsParallel()&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="Linq"&gt;from&lt;/span&gt; col &lt;span class="Statement"&gt;in&lt;/span&gt; Enumerable.Range(0, Width)&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="Linq"&gt;select&lt;/span&gt;&amp;nbsp;&lt;span class="Keyword"&gt;new&lt;/span&gt; { row, col, value = ComputeMandelbrotIndex(row, col) };&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="Statement"&gt;foreach&lt;/span&gt; (&lt;span class="Linq"&gt;var&lt;/span&gt; x &lt;span class="Statement"&gt;in&lt;/span&gt; query)&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; Data[x.row * Width + x.col] = x.value;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;} &lt;/div&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;h4&gt;UnorderedParallelLinqWithStruct&lt;/h4&gt; &lt;p&gt;Creating a new garbage-collected object on the heap for each point isn&amp;#39;t the world&amp;#39;s greatest idea. A very simple transformation is to use a struct instead. Without knowing the PLINQ implementation, it seems likely that the values will still end up on the heap somehow (how else could they be communicated between threads?) but I&amp;#39;d still expect a certain saving from this simple step. &lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div class="code"&gt;&lt;span class="Modifier"&gt;public&lt;/span&gt;&amp;nbsp;&lt;span class="Modifier"&gt;override&lt;/span&gt;&amp;nbsp;&lt;span class="ValueType"&gt;void&lt;/span&gt; Generate()&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="Linq"&gt;var&lt;/span&gt; query = &lt;span class="Linq"&gt;from&lt;/span&gt; row &lt;span class="Statement"&gt;in&lt;/span&gt; Enumerable.Range(0, Height).AsParallel()&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="Linq"&gt;from&lt;/span&gt; col &lt;span class="Statement"&gt;in&lt;/span&gt; Enumerable.Range(0, Width)&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="Linq"&gt;select&lt;/span&gt;&amp;nbsp;&lt;span class="Keyword"&gt;new&lt;/span&gt; Result (row, col, ComputeMandelbrotIndex(row, col));&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="Statement"&gt;foreach&lt;/span&gt; (&lt;span class="Linq"&gt;var&lt;/span&gt; x &lt;span class="Statement"&gt;in&lt;/span&gt; query)&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; Data[x.Row * Width + x.Column] = x.Value;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span class="ValueType"&gt;struct&lt;/span&gt; Result&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="Modifier"&gt;internal&lt;/span&gt;&amp;nbsp;&lt;span class="ValueType"&gt;int&lt;/span&gt; row, col;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="Modifier"&gt;internal&lt;/span&gt;&amp;nbsp;&lt;span class="ValueType"&gt;byte&lt;/span&gt; value;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="Modifier"&gt;internal&lt;/span&gt;&amp;nbsp;&lt;span class="ValueType"&gt;int&lt;/span&gt; Row { get { &lt;span class="Statement"&gt;return&lt;/span&gt; row; } }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="Modifier"&gt;internal&lt;/span&gt;&amp;nbsp;&lt;span class="ValueType"&gt;int&lt;/span&gt; Column { get { &lt;span class="Statement"&gt;return&lt;/span&gt; col; } }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="Modifier"&gt;internal&lt;/span&gt;&amp;nbsp;&lt;span class="ValueType"&gt;byte&lt;/span&gt; Value { get { &lt;span class="Statement"&gt;return&lt;/span&gt; value; } }&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="Modifier"&gt;internal&lt;/span&gt; Result(&lt;span class="ValueType"&gt;int&lt;/span&gt; row, &lt;span class="ValueType"&gt;int&lt;/span&gt; col, &lt;span class="ValueType"&gt;byte&lt;/span&gt; value)&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;.row = row;&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;.col = col;&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;.value = value;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;} &lt;/div&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;h4&gt;UnorderedParallelLinqInPlace&lt;/h4&gt; &lt;p&gt;Why bother returning the data at all? We can just write the data in place, like we did earlier with ParallelLinqRowByRowInPlace but in a more aggressive fashion (and the disadvantage of computing the index for each point). Again, we have to return a dummy value and iterate through those dummy results to force all the computations to go through. &lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div class="code"&gt;&lt;span class="Modifier"&gt;public&lt;/span&gt;&amp;nbsp;&lt;span class="Modifier"&gt;override&lt;/span&gt;&amp;nbsp;&lt;span class="ValueType"&gt;void&lt;/span&gt; Generate()&lt;br /&gt;{&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="Linq"&gt;var&lt;/span&gt; query = &lt;span class="Linq"&gt;from&lt;/span&gt; row &lt;span class="Statement"&gt;in&lt;/span&gt; Enumerable.Range(0, Height).AsParallel()&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="Linq"&gt;from&lt;/span&gt; col &lt;span class="Statement"&gt;in&lt;/span&gt; Enumerable.Range(0, Width)&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="InlineComment"&gt;// Note side-effect!&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; &lt;span class="Linq"&gt;select&lt;/span&gt; Data[row*Width + col] = ComputeMandelbrotIndex(row, col);&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="InlineComment"&gt;// Force iteration through all results&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; query.Max();&lt;br /&gt;} &lt;/div&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;h4&gt;UnorderedParallelLinqInPlaceWithDelegate&lt;/h4&gt; &lt;p&gt;UnorderedParallelLinqInPlace feels slightly nasty - we&amp;#39;ve clearly got a side-effect within the loop, it&amp;#39;s just that we know the side-effects are all orthogonal. We can make ourselves feel slightly cleaner by separating the side-effect from the main algorithm, by way of a delegate. The loop can hold its hands up and say, &amp;quot;I&amp;#39;m side-effect free if you are.&amp;quot; It&amp;#39;s not hugely satisfactory, but it&amp;#39;ll be interesting to see the penalty we pay for this attempt to be purer. &lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div class="code"&gt;IEnumerable&amp;lt;T&amp;gt; Generate&amp;lt;T&amp;gt;(Func&amp;lt;&lt;span class="ValueType"&gt;int&lt;/span&gt;, &lt;span class="ValueType"&gt;int&lt;/span&gt;, T&amp;gt; transformation)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="Linq"&gt;var&lt;/span&gt; query = &lt;span class="Linq"&gt;from&lt;/span&gt; row &lt;span class="Statement"&gt;in&lt;/span&gt; Enumerable.Range(0, Height).AsParallel()&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="Linq"&gt;from&lt;/span&gt; col &lt;span class="Statement"&gt;in&lt;/span&gt; Enumerable.Range(0, Width)&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="InlineComment"&gt;// Side-effect only if transformation contains one...&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; &lt;span class="Linq"&gt;select&lt;/span&gt; transformation(row, col);&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="Statement"&gt;return&lt;/span&gt; query;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span class="Modifier"&gt;public&lt;/span&gt;&amp;nbsp;&lt;span class="Modifier"&gt;override&lt;/span&gt;&amp;nbsp;&lt;span class="ValueType"&gt;void&lt;/span&gt; Generate()&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="InlineComment"&gt;// Transformation with side-effect&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Func&amp;lt;&lt;span class="ValueType"&gt;int&lt;/span&gt;,&lt;span class="ValueType"&gt;int&lt;/span&gt;,&lt;span class="ValueType"&gt;byte&lt;/span&gt;&amp;gt; transformation = (row, col) =&amp;gt; Data[row * Width + col] = ComputeMandelbrotIndex(row, col);&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Generate(transformation).Max();&lt;br /&gt;} &lt;/div&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;h4&gt;UnorderedParallelLinqInPlaceWithGenerator&lt;/h4&gt; &lt;p&gt;We can easily combine the earlier generator code with any of these new ways of processing the results. Here we use our &amp;quot;algorithm in the query&amp;quot; approach but process the results as we go to avoid ordering issues. &lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div class="code"&gt;&lt;span class="Modifier"&gt;public&lt;/span&gt;&amp;nbsp;&lt;span class="Modifier"&gt;override&lt;/span&gt;&amp;nbsp;&lt;span class="ValueType"&gt;void&lt;/span&gt; Generate()&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="Linq"&gt;var&lt;/span&gt; query = &lt;span class="Linq"&gt;from&lt;/span&gt; row &lt;span class="Statement"&gt;in&lt;/span&gt; Enumerable.Range(0, Height).AsParallel()&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="Linq"&gt;from&lt;/span&gt; col &lt;span class="Statement"&gt;in&lt;/span&gt; Enumerable.Range(0, Width)&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="InlineComment"&gt;// Work out the initial complex value from the row and column&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; &lt;span class="Linq"&gt;let&lt;/span&gt; c = &lt;span class="Keyword"&gt;new&lt;/span&gt; Complex((col * SampleWidth) / Width + OffsetX,&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;&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; (row * SampleHeight) / Height + OffsetY)&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="InlineComment"&gt;// Work out the number of iterations&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; &lt;span class="Linq"&gt;let&lt;/span&gt; count = GenerateSequence(c, x =&amp;gt; x * x + c).TakeWhile(x =&amp;gt; x.SquareLength &amp;lt; 4)&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;&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;&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; .Take(MaxIterations)&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;&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;&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; .Count()&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="InlineComment"&gt;// Map that to an appropriate byte value - and write it in place&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; &lt;span class="Linq"&gt;select&lt;/span&gt; Data[row * Width + col]&amp;nbsp; = (&lt;span class="ValueType"&gt;byte&lt;/span&gt;)(count == MaxIterations ? 0 : (count % 255) + 1);&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="InlineComment"&gt;// Force execution&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; query.Max();&lt;br /&gt;} &lt;/div&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;h4&gt;ParallelForLoop&lt;/h4&gt; &lt;p&gt;The Parallel Extensions library doesn&amp;#39;t just contain Parallel LINQ. It also has various other building blocks for parallelism, including a parallel for loop. This allows very simple parallelism of our very first generator - we just turn the outside loop into a parallel for loop, turning the previous inner loop into a delegate. We need to move the index variable into the outer loop so there&amp;#39;ll be one per row (otherwise they&amp;#39;d trample on each other) but that&amp;#39;s about it: &lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div class="code"&gt;&lt;span class="Modifier"&gt;public&lt;/span&gt;&amp;nbsp;&lt;span class="Modifier"&gt;override&lt;/span&gt;&amp;nbsp;&lt;span class="ValueType"&gt;void&lt;/span&gt; Generate()&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Parallel.For(0, Height, row =&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="ValueType"&gt;int&lt;/span&gt; index = row * Width;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="Statement"&gt;for&lt;/span&gt; (&lt;span class="ValueType"&gt;int&lt;/span&gt; col = 0; col &amp;lt; Width; col++)&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; Data[index++] = ComputeMandelbrotIndex(row, col);&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;&amp;nbsp;&lt;/p&gt; &lt;h3&gt;Results&lt;/h3&gt; &lt;p&gt;A benchmark is nothing without results, so here they are on my dual core laptop, from three test runs. The first is the &amp;quot;default&amp;quot; settings I used to develop the benchmark - nothing hugely strenuous, but enough to see differences. I then tried a larger image with the same maximum number of iterations, then the original size with a larger number of iterations. The results are in alphabetical order because that&amp;#39;s how the test prints them :) Times are in milliseconds.&lt;/p&gt; &lt;table cellpadding="2" cellspacing="0"&gt;  &lt;tr&gt; &lt;th&gt;Implementation&lt;/th&gt; &lt;th&gt;Width=1200; MaxIterations=200&lt;/th&gt; &lt;th&gt;Width=3000; MaxIterations=200&lt;/th&gt; &lt;th&gt;Width=1200; MaxIterations=800&lt;/th&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td&gt;MultiThreadRowFetching&lt;/td&gt; &lt;td&gt;380&lt;/td&gt; &lt;td&gt;2479&lt;/td&gt; &lt;td&gt;1311&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td&gt;MultiThreadUpFrontSplitImperative&lt;/td&gt; &lt;td&gt;384&lt;/td&gt; &lt;td&gt;2545&lt;/td&gt; &lt;td&gt;2088&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td&gt;ParallelForLoop&lt;/td&gt; &lt;td&gt;376&lt;/td&gt; &lt;td&gt;2361&lt;/td&gt; &lt;td&gt;1292&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td&gt;ParallelLinqRowByRowInPlace&lt;/td&gt; &lt;td&gt;378&lt;/td&gt; &lt;td&gt;2347&lt;/td&gt; &lt;td&gt;1295&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td&gt;ParallelLinqRowByRowWithCopy&lt;/td&gt; &lt;td&gt;382&lt;/td&gt; &lt;td&gt;2376&lt;/td&gt; &lt;td&gt;1288&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td&gt;ParallelLinqWithGenerator&lt;/td&gt; &lt;td&gt;4782&lt;/td&gt; &lt;td&gt;29752&lt;/td&gt; &lt;td&gt;16626&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td&gt;ParallelLinqWithSequenceOfPoints&lt;/td&gt; &lt;td&gt;549&lt;/td&gt; &lt;td&gt;3413&lt;/td&gt; &lt;td&gt;1462&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td&gt;SingleThreadImperativeInline&lt;/td&gt; &lt;td&gt;684&lt;/td&gt; &lt;td&gt;4352&lt;/td&gt; &lt;td&gt;2455&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td&gt;SingleThreadImperativeSimple&lt;/td&gt; &lt;td&gt;704&lt;/td&gt; &lt;td&gt;4353&lt;/td&gt; &lt;td&gt;2372&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td&gt;SingleThreadImperativeWithComplex&lt;/td&gt; &lt;td&gt;2795&lt;/td&gt; &lt;td&gt;16720&lt;/td&gt; &lt;td&gt;9800&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td&gt;SingleThreadLinqSimple&lt;/td&gt; &lt;td&gt;726&lt;/td&gt; &lt;td&gt;4522&lt;/td&gt; &lt;td&gt;2438&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td&gt;SingleThreadLinqWithGenerator&lt;/td&gt; &lt;td&gt;8902&lt;/td&gt; &lt;td&gt;52586&lt;/td&gt; &lt;td&gt;30075&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td&gt;UnorderedParalleLinqInPlace&lt;/td&gt; &lt;td&gt;422&lt;/td&gt; &lt;td&gt;2586&lt;/td&gt; &lt;td&gt;1317&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td&gt;UnorderedParallelLinqInPlaceWithDelegate&lt;/td&gt; &lt;td&gt;509&lt;/td&gt; &lt;td&gt;3093&lt;/td&gt; &lt;td&gt;1392&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td&gt;UnorderedParallelLinqInPlaceWithGenerator&lt;/td&gt; &lt;td&gt;5046&lt;/td&gt; &lt;td&gt;31657&lt;/td&gt; &lt;td&gt;17026&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td&gt;UnorderedParallelLinqSimple&lt;/td&gt; &lt;td&gt;556&lt;/td&gt; &lt;td&gt;3449&lt;/td&gt; &lt;td&gt;1448&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td&gt;UnorderedParalelLinqWithStruct&lt;/td&gt; &lt;td&gt;511&lt;/td&gt; &lt;td&gt;3227&lt;/td&gt; &lt;td&gt;1427&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt; &lt;h3&gt;Conclusions&lt;/h3&gt; &lt;p&gt;So, what have we learned? Well... bearing in mind that benchmarks like this are often misleading compared with real applications, etc it&amp;#39;s still interesting that:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Parallel Extensions rocks. If I were trying to include a Mandelbrot generation implementation in a production setting, I&amp;#39;d definitely go for the parallel for loop - it&amp;#39;s simple, but works just as well as anything else.&lt;/li&gt; &lt;li&gt;The micro-optimisation of SingleThreadImperativeInline really doesn&amp;#39;t help much, but makes the code harder to understand - just like so many micro-optimisations.&lt;/li&gt; &lt;li&gt;The &amp;quot;generator&amp;quot; form of LINQ really doesn&amp;#39;t perform well at all. It does parallelise pretty well, as you&amp;#39;d expect, but it&amp;#39;s just plain slow.&lt;/li&gt; &lt;li&gt;Part of the slowness is almost certainly due to the use of the &lt;code&gt;Complex&lt;/code&gt; struct, given the results of SingleThreadImperativeWithComplex. Not sure what&amp;#39;s going on there.&lt;/li&gt; &lt;li&gt;The extra abstraction step from UnorderedParallelLinqInPlace to UnorderedParallelLinqInPlaceWithDelegate does have a significant impact, at least when the maximum number of iterations per point isn&amp;#39;t the dominant force. That doesn&amp;#39;t mean it would be a bad idea in production, of course - just somewhere to consider when running against performance issues.&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;I suspect I&amp;#39;ve missed some notable points though - comments?&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1624136" 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/LINQ/default.aspx">LINQ</category><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/Parallelisation/default.aspx">Parallelisation</category></item><item><title>Visualising the Mandelbrot set with LINQ - yet again</title><link>http://msmvps.com/blogs/jon_skeet/archive/2008/02/26/visualising-the-mandelbrot-set-with-linq-yet-again.aspx</link><pubDate>Tue, 26 Feb 2008 20:16:28 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1525235</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=1525235</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/jon_skeet/commentapi.aspx?PostID=1525235</wfw:comment><comments>http://msmvps.com/blogs/jon_skeet/archive/2008/02/26/visualising-the-mandelbrot-set-with-linq-yet-again.aspx#comments</comments><description>&lt;p&gt;I&amp;#39;ve been thinking about ranges again, particularly after &lt;a href="http://csharpindepth.com/ViewNote.aspx?NoteID=48"&gt;catching a book error&lt;/a&gt; just in time, and looking at Marc&amp;#39;s &lt;a href="http://csharpindepth.com/ViewNote.aspx?NoteID=50"&gt;generic complex type&lt;/a&gt;. It struck me that my &lt;a href="http://msmvps.com/blogs/jon.skeet/archive/2007/10/03/linq-to-silliness-generating-a-mandelbrot-with-parallel-potential.aspx"&gt;previous&lt;/a&gt; &lt;a href="http://msmvps.com/blogs/jon.skeet/archive/2007/12/04/a-cautionary-parallel-tale-ordering-isn-t-simple.aspx"&gt;attempts&lt;/a&gt; were all very well, and demonstrated parallelisation quite neatly, but weren&amp;#39;t very LINQy. In particular, they certainly didn&amp;#39;t use LINQ for the tricky part in the same way that &lt;a href="http://blogs.msdn.com/lukeh/archive/2007/04/03/a-ray-tracer-in-c-3-0.aspx"&gt;Luke Hoban&amp;#39;s ray tracer&lt;/a&gt; does.&lt;/p&gt; &lt;p&gt;The thing is, working out the &amp;quot;value&amp;quot; of a particular point in the Mandelbrot set visualisation is actually quite well suited to LINQ:&lt;/p&gt; &lt;ol&gt; &lt;li&gt;Start with a complex value  &lt;li&gt;Apply a transformation to it (square the current value, add the original value from step 1).  &lt;li&gt;Does the result have a modulus &amp;gt; 2? If so, stop.  &lt;li&gt;Have we performed as many iterations as we&amp;#39;re willing to? If so, stop.  &lt;li&gt;Take our new value, and go back to 2.&lt;/li&gt;&lt;/ol&gt; &lt;p&gt;We only need two &amp;quot;extra&amp;quot; bits of code to implement this: a &lt;code&gt;Complex&lt;/code&gt; type, and a way of applying the same transformation repeatedly.&lt;/p&gt; &lt;p&gt;Well, here&amp;#39;s the &lt;code&gt;Complex&lt;/code&gt; type - it contains nothing beyond what we need for this demo, but it&amp;#39;ll do. Obviously Marc&amp;#39;s generic implementation is rather more complete.&lt;/p&gt; &lt;p&gt; &lt;div class="code"&gt;&lt;span class="Modifier"&gt;public&lt;/span&gt;&amp;nbsp;&lt;span class="ValueType"&gt;struct&lt;/span&gt; Complex&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="Modifier"&gt;readonly&lt;/span&gt;&amp;nbsp;&lt;span class="ValueType"&gt;double&lt;/span&gt; real;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="Modifier"&gt;readonly&lt;/span&gt;&amp;nbsp;&lt;span class="ValueType"&gt;double&lt;/span&gt; imaginary;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="Modifier"&gt;public&lt;/span&gt; Complex(&lt;span class="ValueType"&gt;double&lt;/span&gt; real, &lt;span class="ValueType"&gt;double&lt;/span&gt; imaginary)&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;.real = real;&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;.imaginary = imaginary;&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;&amp;nbsp;&lt;span class="Modifier"&gt;static&lt;/span&gt; Complex &lt;span class="Keyword"&gt;operator&lt;/span&gt; +(Complex c1, Complex c2)&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; Complex(c1.real + c2.real, c1.imaginary + c2.imaginary);&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;&amp;nbsp;&lt;span class="Modifier"&gt;static&lt;/span&gt; Complex &lt;span class="Keyword"&gt;operator&lt;/span&gt; *(Complex c1, Complex c2)&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; Complex(c1.real*c2.real - c1.imaginary*c2.imaginary, &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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; c1.real*c2.imaginary + c2.real*c1.imaginary);&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;&amp;nbsp;&lt;span class="ValueType"&gt;double&lt;/span&gt; SquareLength&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; get { &lt;span class="Statement"&gt;return&lt;/span&gt; real * real + imaginary * imaginary; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;} &lt;/div&gt; &lt;p&gt;Simple stuff, assuming you know anything about complex numbers.&lt;/p&gt; &lt;p&gt;The other new piece of code is even simpler. It&amp;#39;s just a &lt;em&gt;generator&lt;/em&gt;. It&amp;#39;s a static method which takes an initial value, and a delegate to apply to one value to get the next. It then lazily returns the generated sequece - forever.&lt;/p&gt; &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; IEnumerable&amp;lt;T&amp;gt; Generate&amp;lt;T&amp;gt;(T start, Func&amp;lt;T, T&amp;gt; step)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; T value = start;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="Statement"&gt;while&lt;/span&gt; (&lt;span class="Keyword"&gt;true&lt;/span&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; yield &lt;span class="Statement"&gt;return&lt;/span&gt; value;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; value = step(value);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;} &lt;/div&gt; &lt;p&gt;&lt;/p&gt; &lt;p&gt;Just as an example of use, remember &lt;code&gt;Enumerable.Range&lt;/code&gt; which starts at a particular integer, then adds one repeatedly until it&amp;#39;s yielded as many results as you&amp;#39;ve asked for? Well, here&amp;#39;s a possible implementation, given the &lt;code&gt;Generate&lt;/code&gt; method:&lt;/p&gt; &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; IEnumerable&amp;lt;&lt;span class="ValueType"&gt;int&lt;/span&gt;&amp;gt; Range(&lt;span class="ValueType"&gt;int&lt;/span&gt; start, &lt;span class="ValueType"&gt;int&lt;/span&gt; count)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="Statement"&gt;return&lt;/span&gt; Generate(start, x =&amp;gt; x + 1).Take(count);&lt;br /&gt;} &lt;/div&gt; &lt;p&gt;&lt;/p&gt; &lt;p&gt;These are all the building blocks we require to build our Mandelbrot visualisation. We want a query which will return a sequence of bytes, one per pixel, where each byte represents the colour to use. Anything which goes beyond our maximum number of iterations ends up black (colour 0) and other values will cycle round the colours. I won&amp;#39;t show the drawing code, but the query is now more self-contained:&lt;/p&gt; &lt;p&gt; &lt;div class="code"&gt;&lt;span class="Linq"&gt;var&lt;/span&gt; query = &lt;span class="Linq"&gt;from&lt;/span&gt; row &lt;span class="Statement"&gt;in&lt;/span&gt; Enumerable.Range(0, ImageHeight)&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="Linq"&gt;from&lt;/span&gt; col &lt;span class="Statement"&gt;in&lt;/span&gt; Enumerable.Range(0, ImageWidth)&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="InlineComment"&gt;// Work out the initial complex value from the row and column&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; &lt;span class="Linq"&gt;let&lt;/span&gt; c = &lt;span class="Keyword"&gt;new&lt;/span&gt; Complex((col * SampleWidth) / ImageWidth + OffsetX,&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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; (row * SampleHeight) / ImageHeight + OffsetY)&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="InlineComment"&gt;// Work out the number of iterations&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; &lt;span class="Linq"&gt;select&lt;/span&gt; Generate(c, x =&amp;gt; x * x + c).TakeWhile(x =&amp;gt; x.SquareLength &amp;lt; 4)&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;&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;&amp;nbsp;&amp;nbsp;&amp;nbsp; .Take(MaxIterations)&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;&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;&amp;nbsp;&amp;nbsp;&amp;nbsp; .Count() &lt;span class="Linq"&gt;into&lt;/span&gt; count&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="InlineComment"&gt;// Map that to an appropriate byte value&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; &lt;span class="Linq"&gt;select&lt;/span&gt; (&lt;span class="ValueType"&gt;byte&lt;/span&gt;)(count == MaxIterations ? 0 : (count % 255) + 1); &lt;/div&gt; &lt;p&gt;&lt;/p&gt; &lt;p&gt;(The various constants used in the expression are defined elsewhere.) This works, and puts the Mandelbrot logic directly into the query. However, I have to admit that it&amp;#39;s &lt;i&gt;much&lt;/i&gt; slower than my earlier versions. Heck, I&amp;#39;m still proud of it though.&lt;/p&gt; &lt;p&gt;As ever, &lt;a href="http://pobox.com/~skeet/csharp/blogfiles/LinqMandelbrot.zip"&gt;full source code is available for download&lt;/a&gt;, should you so wish. &lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1525235" 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/LINQ/default.aspx">LINQ</category><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/Parallelisation/default.aspx">Parallelisation</category></item><item><title>Boxing day</title><link>http://msmvps.com/blogs/jon_skeet/archive/2007/12/26/boxing-day.aspx</link><pubDate>Wed, 26 Dec 2007 20:58:19 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1420711</guid><dc:creator>skeet</dc:creator><slash:comments>5</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/jon_skeet/rsscomments.aspx?PostID=1420711</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/jon_skeet/commentapi.aspx?PostID=1420711</wfw:comment><comments>http://msmvps.com/blogs/jon_skeet/archive/2007/12/26/boxing-day.aspx#comments</comments><description>&lt;p&gt;Here in the UK (and possibly elsewhere - I&amp;#39;m too lazy to check Wikipedia) December 26th is called Boxing Day. I want to know why only this one aspect of .NET is given its own public holiday. Expanding the opportunities to language features as well as those of the runtime, I&amp;#39;d like to see:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Null coalescing day (&amp;quot;Take 3 nulls into the shower? Not me. I just coalesce and go!&amp;quot;)&lt;/li&gt; &lt;li&gt;Type inference day (not popular with HR)&lt;/li&gt; &lt;li&gt;Garbage collection day (as a proper holiday, not just when the bins are collected)&lt;/li&gt; &lt;li&gt;Just-In-Time day (arguably every day for procrastinators such as myself)&lt;/li&gt; &lt;li&gt;Lambda expression day (get those lambdas out of the closet)&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;I could go on, but it&amp;#39;s a pretty thin joke and dinner is ready.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1420711" 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/Wacky+Ideas/default.aspx">Wacky Ideas</category></item></channel></rss>