<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://honestillusion.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>Honest Illusion</title><link>http://honestillusion.com/blogs/default.aspx</link><description>Where Lightning's Still the Biggest Thrill of All...</description><dc:language>en-US</dc:language><generator>CommunityServer 2.1 SP2 (Build: 61129.1)</generator><item><title>Billions &amp; Billions</title><link>http://honestillusion.com/blogs/blog_0/archive/2008/08/26/billions-billions.aspx</link><pubDate>Wed, 27 Aug 2008 02:48:03 GMT</pubDate><guid isPermaLink="false">0c240a87-1bdc-4d60-96f7-7d0531c1460e:6016</guid><dc:creator>James</dc:creator><slash:comments>0</slash:comments><description>
  &lt;p&gt;Recently I got a chain email from a friend, showing the magnitude of a billion.&lt;/p&gt;  &lt;ol&gt;   &lt;ol&gt;     &lt;li&gt;&lt;em&gt;A billion seconds ago it was 1959. &lt;/em&gt;&lt;/li&gt;      &lt;li&gt;&lt;em&gt;A billion minutes ago Jesus was alive. &lt;/em&gt;&lt;/li&gt;      &lt;li&gt;&lt;em&gt;A billion hours ago our ancestors were living in the Stone Age. &lt;/em&gt;&lt;/li&gt;      &lt;li&gt;&lt;em&gt;A billion days ago no-one walked on the earth on two feet. &lt;/em&gt;&lt;/li&gt;      &lt;li&gt;&lt;em&gt;A billion dollars ago was only 8 hours and 20 minutes, at the rate our government is spending it.&lt;/em&gt; &lt;/li&gt;   &lt;/ol&gt; &lt;/ol&gt;  &lt;p&gt;As I normally do with such things, I immediately went to &lt;a href="http://www.snopes.com" target="_blank"&gt;snopes.com&lt;/a&gt; to find out &lt;a href="http://www.snopes.com/inboxer/trivia/billions.asp" target="_blank"&gt;how accurate it was&lt;/a&gt;. (bottom line: eh....close enough, although it was probably written in the early 1990s).&lt;/p&gt;  &lt;p&gt;The interesting thing about it is that it apparently has gone through three phases.  The first had just that bit above about billions.  I guess the politics in that was too subtle for some people, so, more recently someone added a bit about Hurricane Katrina and New Orleans:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;em&gt;Louisiana Senator, Mary Landrieu (D) is presently asking Congress for 250 BILLION DOLLARS to rebuild New Orleans .. Interesting number... what does it mean? &lt;/em&gt;&lt;/p&gt;    &lt;p&gt;&lt;em&gt;A. Well... if you are one of the 484,674 residents of New Orleans (every man, woman, and child) you each get $516,528. &lt;/em&gt;&lt;/p&gt;    &lt;p&gt;&lt;em&gt;B. Or... if you have one of the 188,251 homes in New Orleans, your home gets $1,329,787.&lt;/em&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Snopes dealt with this section as well, but not with their usually efficiency. They pretty much just limited themselves to checking the author's math. (again, close enough, but not perfect, which is odd considering he gave very precise wrong values).  Furthermore, apparently quite recently someone added a bit more, which snopes doesn't cover at all:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;em&gt;Washington, D.C       &lt;br /&gt;&amp;lt; HELLO!&amp;gt;        &lt;br /&gt;Are all your calculators broken?? &lt;/em&gt;&lt;/p&gt;    &lt;p&gt;&lt;em&gt;Accounts Receivable Tax       &lt;br /&gt;Building Permit Tax        &lt;br /&gt;CDL License Tax        &lt;br /&gt;Cigarette Tax        &lt;br /&gt;Corporate Income Tax        &lt;br /&gt;Dog License Tax        &lt;br /&gt;Federal Income Tax         &lt;br /&gt;Federal Unemployment Tax (FUTA)         &lt;br /&gt;Fishing License Tax         &lt;br /&gt;Food License Tax         &lt;br /&gt;Fuel Permit Tax         &lt;br /&gt;Gasoline Tax         &lt;br /&gt;Hunting License Tax         &lt;br /&gt;Inheritance Tax         &lt;br /&gt;Inventory Tax         &lt;br /&gt;IRS Interest Charges (tax on top of tax)         &lt;br /&gt;IRS Penalties (tax on top of tax)         &lt;br /&gt;Liquor Tax         &lt;br /&gt;Luxury Tax         &lt;br /&gt;Marriage License Tax         &lt;br /&gt;Medicare Tax         &lt;br /&gt;Property Tax         &lt;br /&gt;Real Estate Tax         &lt;br /&gt;Service charge taxes         &lt;br /&gt;Social Security Tax         &lt;br /&gt;Road Usage Tax (Truckers)         &lt;br /&gt;Sales Taxes         &lt;br /&gt;Recreational Vehicle Tax        &lt;br /&gt;School Tax        &lt;br /&gt;State Income Tax        &lt;br /&gt;State Unemployment Tax (SUTA)         &lt;br /&gt;Telephone Federal Excise Tax         &lt;br /&gt;Telephone Federal Universal Service Fee Tax         &lt;br /&gt;Telephone Federal, State and Local Surcharge Tax         &lt;br /&gt;Telephone Minimum Usage Surcharge Tax        &lt;br /&gt;Telephone Recurring and Non-recurring Charges Tax        &lt;br /&gt;Telephone State and Local Tax         &lt;br /&gt;Telephone Usage Charge Tax         &lt;br /&gt;Utility Tax         &lt;br /&gt;Vehicle License Registration Tax         &lt;br /&gt;Vehicle Sales Tax         &lt;br /&gt;Watercraft Registration Tax         &lt;br /&gt;Well Permit Tax         &lt;br /&gt;Workers Compensation Tax &lt;/em&gt;&lt;/p&gt;    &lt;p&gt;&lt;em&gt;STILL THINK THIS IS FUNNY? &lt;/em&gt;&lt;/p&gt;    &lt;p&gt;&lt;em&gt;Not one of these taxes existed 100 years ago...       &lt;br /&gt;and our nation was the most prosperous in the world. &lt;/em&gt;&lt;/p&gt;    &lt;p&gt;&lt;em&gt;We had absolutely no national debt...        &lt;br /&gt;We had the largest middle class in the world...         &lt;br /&gt;and Mom stayed home to raise the kids. &lt;/em&gt;&lt;/p&gt;    &lt;p&gt;&lt;em&gt;What happened?       &lt;br /&gt;Can you spell 'politicians!' &lt;/em&gt;&lt;/p&gt;    &lt;p&gt;&lt;em&gt;And I still have to press '1' for English. &lt;/em&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Now, since Snopes dropped the ball on this on, I figured I'd do my part to correct the misinformation here.  &lt;/p&gt;  &lt;p&gt;First of all, as an aside, you can tell the additions were written by a right-winger, as they blame the $250 million on the state's Democratic senator, when in reality the bill was co-sponsored by her and the state's other senator,  Republican David Vitter -- which points to the other sure sign it was written by a right-winger -- it's riddled with errors.  &lt;/p&gt;  &lt;p&gt;The main error is that the money is not just for New Orleans, but for all areas damaged by Katrina -- which includes large parts of Louisiana, Mississippi and bits of Texas.  That pretty much invalidates his whole premise.  But, even if it were just for New Orleans, his premise would still by wrong, because it's not just to rebuild people's houses, but to rebuild the entire city infrastructure: roads, schools, hospitals, levies, etc.  I imagine Republicans would have might less of a problem with government if any of them actually understood how it works.&lt;/p&gt;  &lt;p&gt;Which brings us to the third section of the email, where the writer just goes off the wall.  By line count, it's half of the whole thing, so clearing this guy like hearing himself talk.  Too bad he was too busy typing away to bother actually fact-checking what we wrote.  &lt;/p&gt;  &lt;p&gt;Of that long list of taxes we didn't have "a hundred years ago", many, granted, we didn't have, but mainly because for the most part, the thing being taxed didn't exist (Phones, Social Security, Motor Vehicles etc).  And we really didn't have an income tax in 1908 -- That came about in 1912.  But, as for the rest -- Real estate, alcohol, tobacco,  marriage licenses etc --- They pretty much all were taxed.  &lt;/p&gt;  &lt;p&gt;It's also a bit questionable if we were "&lt;em&gt;the most prosperous [nation] in the world&lt;/em&gt;" in 1908, as we really didn't start moving past England, France and German until after WWI.&lt;/p&gt;  &lt;p&gt;His assertion that "&lt;em&gt;We had absolutely no national debt... &lt;/em&gt;" is total fantasy.  In 1908, the national debt was &lt;a href="http://www.treasurydirect.gov/govt/reports/pd/histdebt/histdebt_histo3.htm" target="_blank"&gt;$2,626,806,271.54&lt;/a&gt;  (adjusted for inflation that would be nearly $58 billion in 2008 dollars).  Granted, that's a lot less than the &lt;a href="http://www.treasurydirect.gov/NP/BPDLogin?application=np" target="_blank"&gt;$9.6 trillion it is now&lt;/a&gt;, but we'll get to that in a minute.   &lt;a href="http://www.treasurydirect.gov/govt/reports/pd/histdebt/histdebt_histo1.htm" target="_blank"&gt;The last time we paid off the debt was 1834.&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;As for "&lt;em&gt;We had the largest middle class in the world... &lt;/em&gt;", again, hard to measure --- Do you count raw number of people (we probably win), or percent of population? (in which case you have to look at England, France and German again).&lt;/p&gt;  &lt;p&gt;"&lt;em&gt;Mom stayed home to raise the kids.&lt;/em&gt;" -- Well, mom did stay at home then, but mostly to run the household, which didn't have electricity, nor, most often, running water.  She had to do this because her husband was working 10 hours a day, 6 days a week at a factory -- earning about a dollar a day.  She didn't spend that much time raising the kids -- because, starting at about age 9 or 10, &lt;a href="http://www.historyplace.com/unitedstates/childlabor/" target="_blank"&gt;they were with the father in the factory.&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Oddly, the writer seems to be blaming the raising national debt on taxes.  Maybe his a fan of Rush Limbaugh, since that's one of his wacky ideas: "The best way to increase government revenue is to cut taxes".  But, in reality, it's a lot like saying "The best way to pay your bills is to quit your job".  A much more reasonably plan would be "The best way to pay your bills is to quit your job,&lt;em&gt;  and get a better job".  &lt;/em&gt;Similarly we could say, "The best way to increase government revenue is to cut taxes, &lt;em&gt;and direct the money to growing the economy&lt;/em&gt;".  But, like the job quitting plan, Republicans seem to leave off the last part --- the important part -- and are happy to let multi-millionaires use their tax breaks to pad out their trust funds.&lt;/p&gt;  &lt;p&gt;Which brings us to the real causes of the national debt:  Wars (historically) and Republican presidents (recently).  The very first time the debt passed &lt;a href="http://www.treasurydirect.gov/govt/reports/pd/histdebt/histdebt_histo2.htm" target="_blank"&gt;$1 billion dollars&lt;/a&gt; was during the Civil War.  That was also it's fastest raise (ten-fold in just two years).  It floated around $2 to $3  billion for about 50 years, when it sudden raises nine-fold in four years just in time for WWI.  Then a slight rise during the Great Depression (tripling over 11 years), followed by a big jump for WWII (five-fold in four years), reaching a &lt;a href="http://www.treasurydirect.gov/govt/reports/pd/histdebt/histdebt_histo3.htm" target="_blank"&gt;quarter of a trillion dollars&lt;/a&gt; by the end.&lt;/p&gt;  &lt;p&gt;The debt grew rather slowly after that, taking 30 years (till 1975) to double again.  Then, under the Reagan administration so-called "Economic boom," it triples, &lt;a href="http://www.treasurydirect.gov/govt/reports/pd/histdebt/histdebt_histo4.htm" target="_blank"&gt;passing one trillion dollars for the first time&lt;/a&gt;.  Overall, Reagan &amp;amp; Bush-41 combined brought the debt from under $1 trillion to over $4 trillion (340%) is just 12 years-- with no significant war.  In contrast, during Clinton's 8 years, it raised only 31%.  And we were poised to start actually paying some of it off.  But with Bush-43, we're back to the old pattern, up 66% in 7 years.&lt;/p&gt;
&lt;div class = "shareblock"&gt;&lt;strong&gt;Share this post:&lt;/strong&gt; &lt;a title="Email Billions+%26amp%3b+Billions" href = "mailto:?body=Thought you might like this: http://honestillusion.com/blogs/blog_0/archive/2008/08/26/billions-billions.aspx&amp;subject=Billions+%26amp%3b+Billions"&gt;Email it!&lt;/a&gt; | &lt;a href = "http://del.icio.us/post?url=http://honestillusion.com/blogs/blog_0/archive/2008/08/26/billions-billions.aspx&amp;title=Billions+%26amp%3b+Billions" title="Submit Billions+%26amp%3b+Billions to del.icio.us" &gt;bookmark it!&lt;/a&gt; | &lt;a href = "http://www.digg.com/submit?url=http://honestillusion.com/blogs/blog_0/archive/2008/08/26/billions-billions.aspx&amp;phase=2" title="Submit Billions+%26amp%3b+Billions to digg.com"&gt;digg it!&lt;/a&gt; | &lt;a href = "http://reddit.com/submit?url=http://honestillusion.com/blogs/blog_0/archive/2008/08/26/billions-billions.aspx&amp;title=Billions+%26amp%3b+Billions" title="Submit Billions+%26amp%3b+Billions to reddit.com"&gt;reddit!&lt;/a&gt;&lt;/div&gt;&lt;img src="http://honestillusion.com/aggbug.aspx?PostID=6016" width="1" height="1"&gt;</description></item><item><title>Lists: Filter, Map and Reduce - and the Magic of IEnumerator.</title><link>http://honestillusion.com/blogs/blog_0/archive/2008/08/25/lists-filter-map-and-reduce-and-the-magic-of-ienumerator.aspx</link><pubDate>Mon, 25 Aug 2008 19:16:16 GMT</pubDate><guid isPermaLink="false">0c240a87-1bdc-4d60-96f7-7d0531c1460e:6014</guid><dc:creator>James</dc:creator><slash:comments>1</slash:comments><description>
  &lt;p&gt;I have this bad habit.  I will frequently stumble upon a blog post describing some new technique, to which I will post a brilliant comment offering an improvement, which, of course, will get lost in the flotsam and jetsam of the blogosphere.  I have to keep reminding myself that is what I have my own blog for.&lt;/p&gt;  &lt;p&gt;Case in point, I recent found this article by Sarah Taraporewalla about writing tradition &lt;a href="http://sarahtaraporewalla.blogspot.com/2008/08/lists-filter-map-and-reduce.html" target="_blank"&gt;Filter, Map and Reduce methods&lt;/a&gt; for Java Lists.  She wondered if they could be written in C#.  I did so in the comments, and now expanded on them here. &lt;/p&gt;  &lt;p&gt;The main difference between mine and those of Sarah's (and also those of &lt;a href="http://dotnet.org.za/pieter/archive/2008/08/17/filter-and-map-in-c.aspx" target="_blank"&gt;Peter&lt;/a&gt;, by way of whose blog I reached Sarah's) is that they pass in a List&amp;lt;&amp;gt; object, and create a new List to return.  This is limiting and unnecessary.&lt;/p&gt;  &lt;pre class="c#"&gt;namespace FilterMapReduce
{
    static public class FMR
    {
        public static IEnumerable&amp;lt;T&amp;gt; Filter&amp;lt;T&amp;gt;(this IEnumerable&amp;lt;T&amp;gt; list, Func&amp;lt;T, bool&amp;gt; filter)
        {
            foreach (T item in list)
            {
                if (filter(item))
                    yield return item;
            }
        }

        public static IEnumerable&amp;lt;T&amp;gt; Map&amp;lt;T&amp;gt;(this IEnumerable&amp;lt;T&amp;gt; list, Func&amp;lt;T, T&amp;gt; map)
        {
            foreach (T item in list)
            {
                yield return map(item);
            }
        }

        public static U Reduce&amp;lt;T, U&amp;gt;(this IEnumerable&amp;lt;T&amp;gt; list, Func&amp;lt;T, U, U&amp;gt; reduce, U accum)
        {
            foreach (T item in list)
            {
                accum = reduce(item, accum);
            }
            return accum;
        }
    }
}&lt;/pre&gt;

&lt;p&gt;I used a number of .Net v3.5 features there -- notably extension methods and the Func&amp;lt;&amp;gt; delegate, but neither is vital (the non-extension version has just a little messier calling syntax, and you'd have to define your own Func delegate replacement -- so, UPGRADE!)&lt;/p&gt;

&lt;p&gt;With those, we can now write code like this:&lt;/p&gt;

&lt;pre class="c#"&gt;int[] nums = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
int sumOdds10 = nums.Filter(n =&amp;gt; (n % 2) == 1)
                    .Map(n =&amp;gt; n * 10)
                    .Reduce((n, a) =&amp;gt; (n + a), 0);&lt;/pre&gt;

&lt;p&gt;I broke the last line to three lines for easier reading, but you could just string it out of you'd like.&lt;/p&gt;

&lt;p&gt;Now that says, "Take the nums array, filter it so we're left with just the odd numbers, map each remaining value to itself times 10, and then sum each of those."&lt;/p&gt;

&lt;p&gt;The important question here is: "How many times have I looped through that array?"  You might think that since I call all three methods, and each has a foreach loop, that it would be only logical that we've go through the array three time.  Logical, maybe, but wrong.   To understand this, let's split that code up a bit:&lt;/p&gt;

&lt;pre class="c#"&gt;var a = nums.Filter(n =&amp;gt; (n % 2) == 1);
var b = a.Map(n =&amp;gt; n * 10);
int sumOdds10 = b.Reduce((n, a) =&amp;gt; (n + a), 0);&lt;/pre&gt;

&lt;p&gt;First we create object a, which if you recall is IEnumerator&amp;lt;int&amp;gt; object. We haven't looped through the array yet -- we just have an object that &lt;em&gt;will&lt;/em&gt; loop throught the array.&lt;/p&gt;

&lt;p&gt;Next, we create object b.  Again, an IEnumerable&amp;lt;int&amp;gt; object, but notably, one which enumerates over, not our array, but the a object.&lt;/p&gt;

&lt;p&gt;Finally, we call Reduce which actually does the work.  It starts to iterate over the list, which is our b object, which is just an IEnumerable object.  So, as we enter Reduce's foreach, it calls &lt;strong&gt;b&lt;/strong&gt;'s (i.e. Map's) MoveNext() method, and enters it's foreach to iterate over the &lt;strong&gt;a&lt;/strong&gt; object -- for which is calls a's (Filter's) MoveNext method.  &lt;/p&gt;

&lt;p&gt;OK, so now we finally enter FIlter's foreach loop, which iterates over an array, so we get a real number (1 at first). It passes the filter so the yield return sends it back to Map, which call the mapping function on it, and yields it up Reduce, which uses it in the reduce function.&lt;/p&gt;

&lt;p&gt;Then Reduce moves on it the next value, which means calling B's MoveNext, which calls Filter's MoveNext, which gets the next value from the array (2).  This fails the filter, so it gets the next value (3), which passes and goes back to Map, and so on, to Reduce.&lt;/p&gt;

&lt;p&gt;In the end, we've only gone through the array once.&lt;/p&gt;
&lt;a href="http://www.dotnetkicks.com/kick/?url=http%3a%2f%2fhonestillusion.com%2fblogs%2fblog_0%2farchive%2f2008%2f08%2f25%2flists-filter-map-and-reduce-and-the-magic-of-ienumerator.aspx"&gt;&lt;img alt="kick it on DotNetKicks.com" src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fhonestillusion.com%2fblogs%2fblog_0%2farchive%2f2008%2f08%2f25%2flists-filter-map-and-reduce-and-the-magic-of-ienumerator.aspx" border="0" /&gt;&lt;/a&gt;
&lt;div class = "shareblock"&gt;&lt;strong&gt;Share this post:&lt;/strong&gt; &lt;a title="Email Lists%3a+Filter%2c+Map+and+Reduce+-+and+the+Magic+of+IEnumerator." href = "mailto:?body=Thought you might like this: http://honestillusion.com/blogs/blog_0/archive/2008/08/25/lists-filter-map-and-reduce-and-the-magic-of-ienumerator.aspx&amp;subject=Lists%3a+Filter%2c+Map+and+Reduce+-+and+the+Magic+of+IEnumerator."&gt;Email it!&lt;/a&gt; | &lt;a href = "http://del.icio.us/post?url=http://honestillusion.com/blogs/blog_0/archive/2008/08/25/lists-filter-map-and-reduce-and-the-magic-of-ienumerator.aspx&amp;title=Lists%3a+Filter%2c+Map+and+Reduce+-+and+the+Magic+of+IEnumerator." title="Submit Lists%3a+Filter%2c+Map+and+Reduce+-+and+the+Magic+of+IEnumerator. to del.icio.us" &gt;bookmark it!&lt;/a&gt; | &lt;a href = "http://www.digg.com/submit?url=http://honestillusion.com/blogs/blog_0/archive/2008/08/25/lists-filter-map-and-reduce-and-the-magic-of-ienumerator.aspx&amp;phase=2" title="Submit Lists%3a+Filter%2c+Map+and+Reduce+-+and+the+Magic+of+IEnumerator. to digg.com"&gt;digg it!&lt;/a&gt; | &lt;a href = "http://reddit.com/submit?url=http://honestillusion.com/blogs/blog_0/archive/2008/08/25/lists-filter-map-and-reduce-and-the-magic-of-ienumerator.aspx&amp;title=Lists%3a+Filter%2c+Map+and+Reduce+-+and+the+Magic+of+IEnumerator." title="Submit Lists%3a+Filter%2c+Map+and+Reduce+-+and+the+Magic+of+IEnumerator. to reddit.com"&gt;reddit!&lt;/a&gt;&lt;/div&gt;&lt;img src="http://honestillusion.com/aggbug.aspx?PostID=6014" width="1" height="1"&gt;</description></item><item><title>Dev102's Challenge #13 : Brackets</title><link>http://honestillusion.com/blogs/blog_0/archive/2008/07/21/dev102-s-challenge-13-brackets.aspx</link><pubDate>Mon, 21 Jul 2008 17:18:03 GMT</pubDate><guid isPermaLink="false">0c240a87-1bdc-4d60-96f7-7d0531c1460e:5391</guid><dc:creator>James</dc:creator><slash:comments>2</slash:comments><description>
  &lt;p&gt;Many people skipped last week's challenge (like I had planned to).  As it turned out, I was the only blogger to responded.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.dev102.com/2008/07/21/a-programming-job-interview-challenge-13-brackets/"&gt;For this week's challenge,&lt;/a&gt; they've gone back to a platform-neutral algorithm question:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;em&gt;Your input is a string which is composed from bracket characters. The allowed characters are:’(', ‘)’, ‘['. ']‘, ‘{’, ‘}’, ‘&amp;lt;’ and ‘&amp;gt;’. Your mission is to determine whether the brackets structure is legal or not.&lt;/em&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;The simple sentence answer is "use a stack, pushing on an open character, and popping on a close character".  There are a few other things to look out for, but that's the basic concept.  For the actual code, I bypassed any kind of library Stack class, since we wanted the most efficient and for the very limited need of this function, I could jury-rig a faster one out of a char array.  Complexity is speed: O(N), space O(N)&lt;/p&gt;  &lt;pre class="c#"&gt;static bool TestBrackets(string testcase)
{
    // create a very simple stack.  
    // Since we push on open &amp;amp; pop an close, stack need only be half the
    // size of the input string.  The +1 is needed because we only check
    // for too many opens after we've pushed.
    char[] stack = new char[(testcase.Length / 2) +1];
    
    int SP=0;
    foreach(char chr in testcase)
    {
        switch(chr)
        {
            // For each open character, push the close char.
            case '[':
                stack[SP++] = ']';
                break;
            case '&amp;lt;':
                stack[SP++] = '&amp;gt;';
                break;
            case '{':
                stack[SP++] = '}';
                break;
            case '(':
                stack[SP++] = ')';
                break;
                
            case ']':
            case '&amp;gt;':
            case '}':
            case ')':
                // check for stack underflow (too many closes)
                // or a character we weren't expecting (bad  nesting)
                if (SP==0 || stack[--SP] != chr)
                    return false;  
                break;
        }
        // Check for stack overflow (too many opens)
        if (SP==stack.Length)
            return false;
    }
    // Finally, it's good if we've closed everything we've opened.
    return SP==0;
}&lt;/pre&gt;
&lt;div class = "shareblock"&gt;&lt;strong&gt;Share this post:&lt;/strong&gt; &lt;a title="Email Dev102%27s+Challenge+%2313+%3a+Brackets" href = "mailto:?body=Thought you might like this: http://honestillusion.com/blogs/blog_0/archive/2008/07/21/dev102-s-challenge-13-brackets.aspx&amp;subject=Dev102%27s+Challenge+%2313+%3a+Brackets"&gt;Email it!&lt;/a&gt; | &lt;a href = "http://del.icio.us/post?url=http://honestillusion.com/blogs/blog_0/archive/2008/07/21/dev102-s-challenge-13-brackets.aspx&amp;title=Dev102%27s+Challenge+%2313+%3a+Brackets" title="Submit Dev102%27s+Challenge+%2313+%3a+Brackets to del.icio.us" &gt;bookmark it!&lt;/a&gt; | &lt;a href = "http://www.digg.com/submit?url=http://honestillusion.com/blogs/blog_0/archive/2008/07/21/dev102-s-challenge-13-brackets.aspx&amp;phase=2" title="Submit Dev102%27s+Challenge+%2313+%3a+Brackets to digg.com"&gt;digg it!&lt;/a&gt; | &lt;a href = "http://reddit.com/submit?url=http://honestillusion.com/blogs/blog_0/archive/2008/07/21/dev102-s-challenge-13-brackets.aspx&amp;title=Dev102%27s+Challenge+%2313+%3a+Brackets" title="Submit Dev102%27s+Challenge+%2313+%3a+Brackets to reddit.com"&gt;reddit!&lt;/a&gt;&lt;/div&gt;&lt;img src="http://honestillusion.com/aggbug.aspx?PostID=5391" width="1" height="1"&gt;</description></item><item><title>Dev102's Challenge #12 : Managed &amp; unmanaged</title><link>http://honestillusion.com/blogs/blog_0/archive/2008/07/16/dev102-s-challenge-12-managed-unmanaged.aspx</link><pubDate>Wed, 16 Jul 2008 18:52:52 GMT</pubDate><guid isPermaLink="false">0c240a87-1bdc-4d60-96f7-7d0531c1460e:5346</guid><dc:creator>James</dc:creator><slash:comments>1</slash:comments><description>
  &lt;p&gt;My solution(s) for last week's challenge were cited, but, only as an "honorable mention" / "also run".&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.dev102.com/2008/07/14/a-programming-job-interview-challenge-12-managed-and-unmanaged/"&gt;This week's challenge&lt;/a&gt; is a different sort of animal.  Not that it is particularly difficult --- actually I suspect it's quite easy --- it's just that it requires a fairly specialize knowledge (Managed Extensions for C++ in this case).  A couple of them in the past required some basic knowledge of .Net &amp;amp; the CLR, but most of the time, the challenge involve a non-platform specific algorithm.&lt;/p&gt;  &lt;p&gt;So, knowing nothing about Managed Extension, I was just going to let this one pass.  But, I happened to run into an old friend (Will Depalo) from my days as a VC++ MVP.  When I went to .Net, I also switched to C#, but he stayed with C++, so I figured he would have some insight.  Reducing the problem to one sentence ("we have a unmanaged class accessing an instance variable of a managed class"), and he immediately  knew the answer ("you'll need to pin it"), and offered some advice ("look up '__pin' in the msdn").  However, didn't realize exactly how good that advice was, as the folk's at DEV102 apparently took the example source code from the __pin article to create the challenge.  So, here's my answer (I love stuff that can be answer via copy'n'paste):&lt;/p&gt;  &lt;p&gt; &lt;/p&gt;  &lt;pre class="c#"&gt;int main() 
{
   ManagedClass &lt;strong&gt;__pin&lt;/strong&gt; * pMngdClass = new ManagedClass;
   UnmanagedClass* pUnmngd = new UnmanagedClass;
   pUnmngd-&amp;gt;incr(&amp;amp;(pMngdClass-&amp;gt;i));
}&lt;/pre&gt;

&lt;p&gt;The rest is unchanged.&lt;/p&gt;
&lt;div class = "shareblock"&gt;&lt;strong&gt;Share this post:&lt;/strong&gt; &lt;a title="Email Dev102%27s+Challenge+%2312+%3a+Managed+%26amp%3b+unmanaged" href = "mailto:?body=Thought you might like this: http://honestillusion.com/blogs/blog_0/archive/2008/07/16/dev102-s-challenge-12-managed-unmanaged.aspx&amp;subject=Dev102%27s+Challenge+%2312+%3a+Managed+%26amp%3b+unmanaged"&gt;Email it!&lt;/a&gt; | &lt;a href = "http://del.icio.us/post?url=http://honestillusion.com/blogs/blog_0/archive/2008/07/16/dev102-s-challenge-12-managed-unmanaged.aspx&amp;title=Dev102%27s+Challenge+%2312+%3a+Managed+%26amp%3b+unmanaged" title="Submit Dev102%27s+Challenge+%2312+%3a+Managed+%26amp%3b+unmanaged to del.icio.us" &gt;bookmark it!&lt;/a&gt; | &lt;a href = "http://www.digg.com/submit?url=http://honestillusion.com/blogs/blog_0/archive/2008/07/16/dev102-s-challenge-12-managed-unmanaged.aspx&amp;phase=2" title="Submit Dev102%27s+Challenge+%2312+%3a+Managed+%26amp%3b+unmanaged to digg.com"&gt;digg it!&lt;/a&gt; | &lt;a href = "http://reddit.com/submit?url=http://honestillusion.com/blogs/blog_0/archive/2008/07/16/dev102-s-challenge-12-managed-unmanaged.aspx&amp;title=Dev102%27s+Challenge+%2312+%3a+Managed+%26amp%3b+unmanaged" title="Submit Dev102%27s+Challenge+%2312+%3a+Managed+%26amp%3b+unmanaged to reddit.com"&gt;reddit!&lt;/a&gt;&lt;/div&gt;&lt;img src="http://honestillusion.com/aggbug.aspx?PostID=5346" width="1" height="1"&gt;</description></item><item><title>Dev102's Challenge #11 - Summing Numbers</title><link>http://honestillusion.com/blogs/blog_0/archive/2008/07/08/dev102-s-challenge-11-summing-numbers.aspx</link><pubDate>Tue, 08 Jul 2008 13:55:37 GMT</pubDate><guid isPermaLink="false">0c240a87-1bdc-4d60-96f7-7d0531c1460e:5203</guid><dc:creator>James</dc:creator><slash:comments>1</slash:comments><description>
  &lt;p&gt;My answer was acknowledged as correct for last week's challenge.  So, let's see if we can make it two in a row.  &lt;a href="http://www.dev102.com/misc/a-programming-job-interview-challenge-11-summing-numbers/"&gt;This week&lt;/a&gt;: &lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;em&gt;Given a list of n integers and another integer called m, determine (true / false) if there exist 2 numbers in that list which sum up to m.       &lt;br /&gt;Example: 2,6,4,9,1,12,7 and m=14 -&amp;gt; 2 and 12 sum up to 14, so the answer is true.&lt;/em&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;This one is rather tricky.  There is no obvious (to me) solution.   I can see three viable methods, each with its own pros &amp;amp; cons.&lt;/p&gt;  &lt;p&gt;Method 1: We'll call this "brute force".  The obvious answer.  We add the values of list[1] and list[2],  then list[1] and list[3], then list[1] and list[4] and so forth, until we reach list[1] and list[ n ].  If we haven't found a match yet, we then move on to adding list[2] to list[3], then list[2] to list[4] etc. In code that would be: &lt;/p&gt;  &lt;pre class="c#"&gt;for(int i= 0; i &amp;lt;N-1; ++i) 
    for(int j= i+1; j &amp;lt; N; ++j) 
       if (list[ i ] + list[ j ] == M) &lt;/pre&gt;

&lt;p&gt;The complexity for this would be Summation N which is officially O(N*N) (although it's closer to O(N*N/2) ).  However, that's the worst case: we can exit early as soon as we find a valid match, making the average case O(N*N/4).  It's also important to note the basic operation that's being repeated (adding two number) is very fast.  Hence, this would be the winner for small values of N (and probably some very large "small values of N").&lt;/p&gt;

&lt;p&gt;Method 2: Which we'll call the "bi-directional search".  This would clearly be the winner, except for it's precondition: start with a sorted list.  Add the first and last elements of the list (list[1] + list[ N ]).  If they equal to goal, we're done. If they are more than the goal, add the first and second-to-last elements(list[1] + list[ N-1 ]).  If they are less, then add the second element to the last element (list[2] + list[ N ]).  Continue this way, moving up from the front when the sum is too low, and down from the back when it's too high until you either find a match, or meet in the middle.  The complexity of this algorithm in O(N) --- for a sorted list.  We're given an unsorted list, which means we'd have to sort it first.  Sorting is, at best, O(N*logN), making the total complexity O(N*logN + N), which I believe is still less than method 1, but the basic task being done for the sort (comparing &lt;em&gt;and&lt;/em&gt;  swapping) is much more expensive than for method 1.  Further, you must complete the sort before you can start the search, so you've taken the big hit before you get a chance for an early exit, making the average case O(NlogN+N/2), so this will win for large values of N, but they'd have to be &lt;em&gt;very&lt;/em&gt; large values of N.&lt;/p&gt;

&lt;p&gt;And, finally, Method 3, which we'll call the "partitioned search". Partition the list into two sublists, one with values less the M/2 and one with values greater than M/2. (The value equal to M/2 can be ignored, as we would need two of them, and we've been assured that the values in the list are unique).  If a solution exists, it will require one from each list; any combination of two from the lower sublist will be two low.  Any two from the upper list will be too high. So we just try every combination of one from each sublist.   In the worst case, that's O((N/2) * (N/2)) or O(N*N/4),  with an average case of O(N*N/8).  To explain with examples: Say we are given a list of 10 numbers.  Method 1 would require 55 additions to try every possibility. If we partitions the list into sublists of 5 &amp;amp; 5, then this method would require only 25 additions.  However, if the numbers break down so that the partitions are 8 &amp;amp; 2, then we'd need only 16 additions.  And, as before, we can exit early as soon as we find a match.  Partitioning can be done in O(N): Start by pointing at the first and last elements, just as in Method 2. Seek forward looking for an element greater than N/2.  When one is found, seek from the end, looking for an element less then N/2. When you have one of each, swap 'em and continue.  When the pointers meet, the list is partitioned in place.  That required only one pass through the list, so the step is O(N), making the total for the average case O(N*N/8 + N).&lt;/p&gt;

&lt;p&gt;Overall, Method 1 wins for small lists, Method 3 for larger lists, and Method 2 for very large lists.  Since memory read/write efficiency is the last bottleneck (how many additions is one swap worth?) the exact point where one method passes another is heavily platform dependant.&lt;/p&gt;

&lt;p&gt;In the back of my mind, two other ideas for other methods keep flowing through. The first tells me that there should be some way to accomplish this through summing the list.  This would be O(N), but I just can't think of a way to make it work.  The other involves building a matrix.  I'm pretty sure I could make that work, in a way that O(N) once the matrix is built, but building it would be greater the O(N) itself, so the whole task would be no faster than the means described above.&lt;/p&gt;
&lt;div class = "shareblock"&gt;&lt;strong&gt;Share this post:&lt;/strong&gt; &lt;a title="Email Dev102%27s+Challenge+%2311+-+Summing+Numbers" href = "mailto:?body=Thought you might like this: http://honestillusion.com/blogs/blog_0/archive/2008/07/08/dev102-s-challenge-11-summing-numbers.aspx&amp;subject=Dev102%27s+Challenge+%2311+-+Summing+Numbers"&gt;Email it!&lt;/a&gt; | &lt;a href = "http://del.icio.us/post?url=http://honestillusion.com/blogs/blog_0/archive/2008/07/08/dev102-s-challenge-11-summing-numbers.aspx&amp;title=Dev102%27s+Challenge+%2311+-+Summing+Numbers" title="Submit Dev102%27s+Challenge+%2311+-+Summing+Numbers to del.icio.us" &gt;bookmark it!&lt;/a&gt; | &lt;a href = "http://www.digg.com/submit?url=http://honestillusion.com/blogs/blog_0/archive/2008/07/08/dev102-s-challenge-11-summing-numbers.aspx&amp;phase=2" title="Submit Dev102%27s+Challenge+%2311+-+Summing+Numbers to digg.com"&gt;digg it!&lt;/a&gt; | &lt;a href = "http://reddit.com/submit?url=http://honestillusion.com/blogs/blog_0/archive/2008/07/08/dev102-s-challenge-11-summing-numbers.aspx&amp;title=Dev102%27s+Challenge+%2311+-+Summing+Numbers" title="Submit Dev102%27s+Challenge+%2311+-+Summing+Numbers to reddit.com"&gt;reddit!&lt;/a&gt;&lt;/div&gt;&lt;img src="http://honestillusion.com/aggbug.aspx?PostID=5203" width="1" height="1"&gt;</description></item><item><title>Dev102's Challenge #10 - The Missing Number</title><link>http://honestillusion.com/blogs/blog_0/archive/2008/07/01/dev102-s-challenge-10-the-missing-number.aspx</link><pubDate>Tue, 01 Jul 2008 18:50:34 GMT</pubDate><guid isPermaLink="false">0c240a87-1bdc-4d60-96f7-7d0531c1460e:5140</guid><dc:creator>James</dc:creator><slash:comments>1</slash:comments><description>
  &lt;p&gt;I didn't actually skip last week's challenge for Dev102.  I did write up a solution.  I just forgot to post it.  It was wrong anyway.&lt;/p&gt;  &lt;p&gt;Well, no sense it looking backward... &lt;a href="http://www.dev102.com/net/a-programming-job-interview-challenge-10-the-missing-number/"&gt;This week's&lt;/a&gt;:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;em&gt;Your input is an unsorted list of n numbers ranging from 1 to n+1, all of the numbers are unique, meaning that a number can’t appear twice in that list. ..One of the numbers is missing and you are asked to provide the most efficient method to find that missing number.&lt;/em&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;And Shahar was right, it was rather easy.  We just add up the number we get, and subtract that value from the sum we should have gotten if the missing number wasn't missing.&lt;/p&gt;  &lt;p&gt;int FindMissingNumber(IEnumerable&amp;lt;int&amp;gt; list)    &lt;br /&gt;{     &lt;br /&gt;    int actualSum = 0;     &lt;br /&gt;    int expectedSum = 0;     &lt;br /&gt;    int n = 1;     &lt;br /&gt;    foreach(int i in list)     &lt;br /&gt;    {     &lt;br /&gt;        actualSum += i;     &lt;br /&gt;        expectedSum += n++;     &lt;br /&gt;    }     &lt;br /&gt;    expectedSum += n;     &lt;br /&gt;    return expectedSum - actualSum;     &lt;br /&gt;} &lt;/p&gt;  &lt;p&gt; &lt;/p&gt;  &lt;p&gt;Things to note:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;The complexity of the algorithm in O(n).   &lt;/li&gt;    &lt;li&gt;I  assured that complexity by using the least powerful collection interface (IEnumerable), and iterated through it only once. &lt;/li&gt;    &lt;li&gt;I summed the expected total manually instead of an formula on list.Count, but for some collection types (such as a linked lists) Count is, by itself, O(n). &lt;/li&gt;    &lt;li&gt;The method will work for an empty sequence, returning 1. &lt;/li&gt; &lt;/ul&gt;
&lt;div class = "shareblock"&gt;&lt;strong&gt;Share this post:&lt;/strong&gt; &lt;a title="Email Dev102%27s+Challenge+%2310+-+The+Missing+Number" href = "mailto:?body=Thought you might like this: http://honestillusion.com/blogs/blog_0/archive/2008/07/01/dev102-s-challenge-10-the-missing-number.aspx&amp;subject=Dev102%27s+Challenge+%2310+-+The+Missing+Number"&gt;Email it!&lt;/a&gt; | &lt;a href = "http://del.icio.us/post?url=http://honestillusion.com/blogs/blog_0/archive/2008/07/01/dev102-s-challenge-10-the-missing-number.aspx&amp;title=Dev102%27s+Challenge+%2310+-+The+Missing+Number" title="Submit Dev102%27s+Challenge+%2310+-+The+Missing+Number to del.icio.us" &gt;bookmark it!&lt;/a&gt; | &lt;a href = "http://www.digg.com/submit?url=http://honestillusion.com/blogs/blog_0/archive/2008/07/01/dev102-s-challenge-10-the-missing-number.aspx&amp;phase=2" title="Submit Dev102%27s+Challenge+%2310+-+The+Missing+Number to digg.com"&gt;digg it!&lt;/a&gt; | &lt;a href = "http://reddit.com/submit?url=http://honestillusion.com/blogs/blog_0/archive/2008/07/01/dev102-s-challenge-10-the-missing-number.aspx&amp;title=Dev102%27s+Challenge+%2310+-+The+Missing+Number" title="Submit Dev102%27s+Challenge+%2310+-+The+Missing+Number to reddit.com"&gt;reddit!&lt;/a&gt;&lt;/div&gt;&lt;img src="http://honestillusion.com/aggbug.aspx?PostID=5140" width="1" height="1"&gt;</description></item><item><title>DEV102's Programming Job Interview Challenge #8</title><link>http://honestillusion.com/blogs/blog_0/archive/2008/06/18/dev102-s-programming-job-interview-challenge-8.aspx</link><pubDate>Wed, 18 Jun 2008 19:23:13 GMT</pubDate><guid isPermaLink="false">0c240a87-1bdc-4d60-96f7-7d0531c1460e:5059</guid><dc:creator>James</dc:creator><slash:comments>1</slash:comments><description>
  &lt;p&gt;
    &lt;a href="http://www.dev102.com/net/a-programming-job-interview-challenge-7-coins-of-the-round-table/"&gt;I skipped last week's DEV102 challenge&lt;/a&gt;.   I didn't think my answer was right.  Turns out that it was. I was assuming that it had a limitation that would disqualify it.  I assumed that my solution would only work if you placed the coins in a tight grid with each newly-placed coin touching an existing coin.  As a practical matter, this is true.  It would be virtually impossible to properly place a coin mirroring the freely-placed previous coin without resorting to a tape measure and protractor.  And the placement would have to be exact for it to work.  So I suppressed my solution for lack of practicality, when all they really wanted was a theoretic solution. &lt;/p&gt;  &lt;p&gt;Anyway, onward to &lt;a href="http://www.dev102.com/net/a-programming-job-interview-challenge-8-a-needle-in-a-haystack/"&gt;this week's challenge, #8&lt;/a&gt; (excerpted):&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;You are writing a software component that receives a binary record every 20 millisecond. .... Your component goal is to alert whenever it identifies a specific expression (which is provided at the initialization process) in the stream of records - you are looking for a specific combination of binary records. &lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;The answer is, of course, a &lt;a href="http://en.wikipedia.org/wiki/Finite_State_Machine"&gt;&lt;strong&gt;Finite State Machine&lt;/strong&gt;&lt;/a&gt;. To explain how one works, we need to come up with a example expression to search for.  Let's say these records come it four formats: Type A, type B, type C and Type D, and we are looking a sequence of records in the following pattern: ABACB (if you'd like, you can assume that there are many record types, and Type D represents "any record that's not type A, B or C").  So, we start in state "0". State 0 can be called "looking for first A record".  At state 0, if we find an A record, we move into state 1 ("Find first A, looking for first B").  If we find any other kind of record, we stay in state 0.  This can be expressed in table form as:&lt;/p&gt;  &lt;div align="center"&gt;   &lt;table cellspacing="0" cellpadding="2" align="center"&gt;       &lt;tr&gt;         &lt;td&gt; &lt;/td&gt;          &lt;td&gt;Next state&lt;/td&gt;          &lt;td&gt;when &lt;/td&gt;          &lt;td&gt;record &lt;/td&gt;          &lt;td&gt;found&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td&gt;Current State VV&lt;/td&gt;          &lt;td&gt;A&lt;/td&gt;          &lt;td&gt;B&lt;/td&gt;          &lt;td&gt;C&lt;/td&gt;          &lt;td&gt;D&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td&gt;0&lt;/td&gt;          &lt;td&gt;1&lt;/td&gt;          &lt;td&gt;0&lt;/td&gt;          &lt;td&gt;0&lt;/td&gt;          &lt;td&gt;0&lt;/td&gt;       &lt;/tr&gt;     &lt;/table&gt; &lt;/div&gt;  &lt;p&gt;Next when we are in state 1, if we find a B record, we move into state 2, but the other transitions are a bit trickier.  If we find a C or D, we're back to state 0 ("looking for 1st A"), but if we find another A, we have to stay in state 1.  Adding that to our graph:&lt;/p&gt;  &lt;div align="center"&gt;   &lt;table cellspacing="0" cellpadding="2" align="center"&gt;       &lt;tr&gt;         &lt;td&gt; &lt;/td&gt;          &lt;td&gt;Next state&lt;/td&gt;          &lt;td&gt;when &lt;/td&gt;          &lt;td&gt;record &lt;/td&gt;          &lt;td&gt;found&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td&gt;Current State VV&lt;/td&gt;          &lt;td&gt;A&lt;/td&gt;          &lt;td&gt;B&lt;/td&gt;          &lt;td&gt;C&lt;/td&gt;          &lt;td&gt;D&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td&gt;0&lt;/td&gt;          &lt;td&gt;1&lt;/td&gt;          &lt;td&gt;0&lt;/td&gt;          &lt;td&gt;0&lt;/td&gt;          &lt;td&gt;0&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td&gt;1&lt;/td&gt;          &lt;td&gt;1&lt;/td&gt;          &lt;td&gt;2&lt;/td&gt;          &lt;td&gt;0&lt;/td&gt;          &lt;td&gt;0&lt;/td&gt;       &lt;/tr&gt;     &lt;/table&gt; &lt;/div&gt;  &lt;p&gt; &lt;/p&gt;  &lt;p&gt;Ok, now, we are in state 2 ("found AB, looking for 2nd A"), Here if we find an A, we move on to state 3 --- anything else, and we're back to state 0.&lt;/p&gt;  &lt;div align="center"&gt;   &lt;table cellspacing="0" cellpadding="2" align="center"&gt;       &lt;tr&gt;         &lt;td&gt; &lt;/td&gt;          &lt;td&gt;Next state&lt;/td&gt;          &lt;td&gt;when &lt;/td&gt;          &lt;td&gt;record &lt;/td&gt;          &lt;td&gt;found&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td&gt;Current State VV&lt;/td&gt;          &lt;td&gt;A&lt;/td&gt;          &lt;td&gt;B&lt;/td&gt;          &lt;td&gt;C&lt;/td&gt;          &lt;td&gt;D&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td&gt;0&lt;/td&gt;          &lt;td&gt;1&lt;/td&gt;          &lt;td&gt;0&lt;/td&gt;          &lt;td&gt;0&lt;/td&gt;          &lt;td&gt;0&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td&gt;1&lt;/td&gt;          &lt;td&gt;1&lt;/td&gt;          &lt;td&gt;2&lt;/td&gt;          &lt;td&gt;0&lt;/td&gt;          &lt;td&gt;0&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td&gt;2&lt;/td&gt;          &lt;td&gt;3&lt;/td&gt;          &lt;td&gt;0&lt;/td&gt;          &lt;td&gt;0&lt;/td&gt;          &lt;td&gt;0&lt;/td&gt;       &lt;/tr&gt;     &lt;/table&gt; &lt;/div&gt;  &lt;p&gt;State 3 ("found ABA, looking for C"), is a bit trickier again.  If we find a C, naturally, we move into state 4. And if we find a D, were back into state 0.  But, if we an A, we step back to state 1.  And if we find a B, we step back only to state 2 (ie, we've found "ABAB" and the second "AB" may be the start of the pattern we want.&lt;/p&gt;  &lt;div align="center"&gt;   &lt;table cellspacing="0" cellpadding="2" align="center"&gt;       &lt;tr&gt;         &lt;td&gt; &lt;/td&gt;          &lt;td&gt;Next state&lt;/td&gt;          &lt;td&gt;when &lt;/td&gt;          &lt;td&gt;record &lt;/td&gt;          &lt;td&gt;found&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td&gt;Current State VV&lt;/td&gt;          &lt;td&gt;A&lt;/td&gt;          &lt;td&gt;B&lt;/td&gt;          &lt;td&gt;C&lt;/td&gt;          &lt;td&gt;D&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td&gt;0&lt;/td&gt;          &lt;td&gt;1&lt;/td&gt;          &lt;td&gt;0&lt;/td&gt;          &lt;td&gt;0&lt;/td&gt;          &lt;td&gt;0&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td&gt;1&lt;/td&gt;          &lt;td&gt;1&lt;/td&gt;          &lt;td&gt;2&lt;/td&gt;          &lt;td&gt;0&lt;/td&gt;          &lt;td&gt;0&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td&gt;2&lt;/td&gt;          &lt;td&gt;3&lt;/td&gt;          &lt;td&gt;0&lt;/td&gt;          &lt;td&gt;0&lt;/td&gt;          &lt;td&gt;0&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td&gt;3&lt;/td&gt;          &lt;td&gt;1&lt;/td&gt;          &lt;td&gt;2&lt;/td&gt;          &lt;td&gt;4&lt;/td&gt;          &lt;td&gt;0&lt;/td&gt;       &lt;/tr&gt;     &lt;/table&gt; &lt;/div&gt;  &lt;p&gt;At state 4, we enter the endgame.  We're trying to find "ABACB", and so far we're found "ABAC".  If the next record is a B, we have success ("Let loose the pigeons!").  If it's an A, we go to state 1 (as usually). Anything else, and we start over at state 0.&lt;/p&gt;  &lt;div align="center"&gt;   &lt;table cellspacing="0" cellpadding="2" align="center"&gt;       &lt;tr&gt;         &lt;td&gt; &lt;/td&gt;          &lt;td&gt;Next state&lt;/td&gt;          &lt;td&gt;when &lt;/td&gt;          &lt;td&gt;record &lt;/td&gt;          &lt;td&gt;found&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td&gt;Current State VV&lt;/td&gt;          &lt;td&gt;A&lt;/td&gt;          &lt;td&gt;B&lt;/td&gt;          &lt;td&gt;C&lt;/td&gt;          &lt;td&gt;D&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td&gt;0&lt;/td&gt;          &lt;td&gt;1&lt;/td&gt;          &lt;td&gt;0&lt;/td&gt;          &lt;td&gt;0&lt;/td&gt;          &lt;td&gt;0&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td&gt;1&lt;/td&gt;          &lt;td&gt;1&lt;/td&gt;          &lt;td&gt;2&lt;/td&gt;          &lt;td&gt;0&lt;/td&gt;          &lt;td&gt;0&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td&gt;2&lt;/td&gt;          &lt;td&gt;3&lt;/td&gt;          &lt;td&gt;0&lt;/td&gt;          &lt;td&gt;0&lt;/td&gt;          &lt;td&gt;0&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td&gt;3&lt;/td&gt;          &lt;td&gt;1&lt;/td&gt;          &lt;td&gt;2&lt;/td&gt;          &lt;td&gt;4&lt;/td&gt;          &lt;td&gt;0&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td&gt;4&lt;/td&gt;          &lt;td&gt;1&lt;/td&gt;          &lt;td&gt;&lt;strong&gt;*&lt;/strong&gt;&lt;/td&gt;          &lt;td&gt;0&lt;/td&gt;          &lt;td&gt;0&lt;/td&gt;       &lt;/tr&gt;     &lt;/table&gt; &lt;/div&gt;  &lt;p&gt;Now, to put this into C# code, we merely need a simple pre-initialize int array following the structure of the chart we just built, and start with our state at 0.&lt;/p&gt;  &lt;p&gt;const int[,] states = new int [5,4]{&lt;/p&gt;  &lt;p&gt;{ 1,0,0,0},&lt;/p&gt;  &lt;p&gt;{1,2,0,0}&lt;/p&gt;  &lt;p&gt;{3,0,0,0}&lt;/p&gt;  &lt;p&gt;{1,2,4,0}&lt;/p&gt;  &lt;p&gt;{1,-1,0,0}&lt;/p&gt;  &lt;p&gt;};&lt;/p&gt;  &lt;p&gt;int state = 0;&lt;/p&gt;  &lt;p&gt; &lt;/p&gt;  &lt;p&gt;Then as a new record comes in, we just determine it's type, and update the state:&lt;/p&gt;  &lt;p&gt;bool MatchFound(Record newRecord)    &lt;br /&gt;{&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;// return 0,1,2 or 3 for record type A,B,C or D respectively.      &lt;br /&gt;// can be assumed to be present, as per the spec.       &lt;br /&gt;int type = GetRecordType(newRecord);&lt;/p&gt;    &lt;p&gt;// Here's where the magic happens      &lt;br /&gt;// just a simple index into an array.       &lt;br /&gt;state = states[state, type];&lt;/p&gt;    &lt;p&gt;return state &amp;lt; 0;    // Report success or failure.&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;}&lt;/p&gt;  &lt;p&gt; And that's it.  Total state held between records: one integer.  Total work needed per record to determine pattern: one array lookup and one int comparison. &lt;/p&gt;  &lt;p&gt;And the real beauty of this approach is that if we wanted to look for other patterns &lt;em&gt;at the same time&lt;/em&gt;, it could be done. For example, by just changing the states[] array in the above to this&lt;/p&gt;  &lt;p&gt;const int[,] states = new int [13,4]{&lt;/p&gt;  &lt;p&gt; {1,5,9,0},     &lt;br /&gt; {1,2,9,0},    &lt;br /&gt; {3,6,9,0},    &lt;br /&gt; {1,2,4,0},    &lt;br /&gt; {10,-1,9,0},    &lt;br /&gt; {1, 6, 9, 0},    &lt;br /&gt; {1, 6, 7, 0},    &lt;br /&gt; {10, 5, 8, 0},    &lt;br /&gt; {-2, 5, 9, 0},    &lt;br /&gt; {10,5, 9, 0},  &lt;br /&gt;{1, 11, 9, 0},  &lt;br /&gt;{3, 6, 12, 0},     &lt;br /&gt;{-3, 6, 9, 0} &lt;/p&gt;  &lt;p&gt;};&lt;/p&gt;  &lt;p&gt;Then we'd be able to search for ABACB (as before, found when state = -1) and BBCCA (found when state = -2), plus one more pattern (found when state = -3).&lt;/p&gt;  &lt;h3&gt;Class Homework&lt;/h3&gt;  &lt;p&gt;1) (simple) Try to figure out the third pattern that can be found using that state table. (It's a sequence of 5 records using just A B &amp;amp; C)&lt;/p&gt;  &lt;p&gt;2) (hopefully not possible)  Try to figure out a sequence of records that would cause the state machine to miss one of those patterns (Note: after one is found, we start over at state 0, so it's not intended to find overlapping sequences, such as "ABACBBCCA".  It's find the first but not the second.)&lt;/p&gt;
&lt;div class = "shareblock"&gt;&lt;strong&gt;Share this post:&lt;/strong&gt; &lt;a title="Email DEV102%27s+Programming+Job+Interview+Challenge+%238" href = "mailto:?body=Thought you might like this: http://honestillusion.com/blogs/blog_0/archive/2008/06/18/dev102-s-programming-job-interview-challenge-8.aspx&amp;subject=DEV102%27s+Programming+Job+Interview+Challenge+%238"&gt;Email it!&lt;/a&gt; | &lt;a href = "http://del.icio.us/post?url=http://honestillusion.com/blogs/blog_0/archive/2008/06/18/dev102-s-programming-job-interview-challenge-8.aspx&amp;title=DEV102%27s+Programming+Job+Interview+Challenge+%238" title="Submit DEV102%27s+Programming+Job+Interview+Challenge+%238 to del.icio.us" &gt;bookmark it!&lt;/a&gt; | &lt;a href = "http://www.digg.com/submit?url=http://honestillusion.com/blogs/blog_0/archive/2008/06/18/dev102-s-programming-job-interview-challenge-8.aspx&amp;phase=2" title="Submit DEV102%27s+Programming+Job+Interview+Challenge+%238 to digg.com"&gt;digg it!&lt;/a&gt; | &lt;a href = "http://reddit.com/submit?url=http://honestillusion.com/blogs/blog_0/archive/2008/06/18/dev102-s-programming-job-interview-challenge-8.aspx&amp;title=DEV102%27s+Programming+Job+Interview+Challenge+%238" title="Submit DEV102%27s+Programming+Job+Interview+Challenge+%238 to reddit.com"&gt;reddit!&lt;/a&gt;&lt;/div&gt;&lt;img src="http://honestillusion.com/aggbug.aspx?PostID=5059" width="1" height="1"&gt;</description></item><item><title>DEV102's Programming Job Interview Challenge #6 </title><link>http://honestillusion.com/blogs/blog_0/archive/2008/06/02/dev102-s-programming-job-interview-challenge-6.aspx</link><pubDate>Mon, 02 Jun 2008 14:16:00 GMT</pubDate><guid isPermaLink="false">0c240a87-1bdc-4d60-96f7-7d0531c1460e:4914</guid><dc:creator>James</dc:creator><slash:comments>0</slash:comments><description>
  &lt;p&gt;Another week, another C# interview question from the good folk's at Dev102.com -- Although I use the term "good folks" advisedly, as this week they did not even acknowledge the solution I posted for last weeks puzzle (which was both correct, and, I believe, the first blog post about it).&lt;/p&gt;

&lt;p&gt;Anyway, time to move on to &lt;a href="http://www.dev102.com/2008/06/02/a-programming-job-interview-challenge-6-c-games/"&gt;this week's question&lt;/a&gt;. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Look at the following Code segment written in C#:&lt;/p&gt;
&lt;div&gt;
&lt;div style="border-style:none;padding:0px;overflow:visible;font-size:8pt;width:100%;color:black;line-height:12pt;"&gt;
&lt;pre style="border-style:none;margin:0em;padding:0px;overflow:visible;font-size:8pt;width:100%;color:black;line-height:12pt;"&gt;&lt;span&gt;   1:&lt;/span&gt; ArrayList a = &lt;span&gt;new&lt;/span&gt; ArrayList();&lt;/pre&gt;
&lt;pre style="border-style:none;margin:0em;padding:0px;overflow:visible;font-size:8pt;width:100%;color:black;line-height:12pt;"&gt;&lt;span&gt;   2:&lt;/span&gt; ArrayList b = &lt;span&gt;new&lt;/span&gt; ArrayList();&lt;/pre&gt;
&lt;pre style="border-style:none;margin:0em;padding:0px;overflow:visible;font-size:8pt;width:100%;color:black;line-height:12pt;"&gt;&lt;span&gt;   3:&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="border-style:none;margin:0em;padding:0px;overflow:visible;font-size:8pt;width:100%;color:black;line-height:12pt;"&gt;&lt;span&gt;   4:&lt;/span&gt; a.Add(1);&lt;/pre&gt;
&lt;pre style="border-style:none;margin:0em;padding:0px;overflow:visible;font-size:8pt;width:100%;color:black;line-height:12pt;"&gt;&lt;span&gt;   5:&lt;/span&gt; b.Add(1);&lt;/pre&gt;
&lt;pre style="border-style:none;margin:0em;padding:0px;overflow:visible;font-size:8pt;width:100%;color:black;line-height:12pt;"&gt;&lt;span&gt;   6:&lt;/span&gt; a.Add(2);&lt;/pre&gt;
&lt;pre style="border-style:none;margin:0em;padding:0px;overflow:visible;font-size:8pt;width:100%;color:black;line-height:12pt;"&gt;&lt;span&gt;   7:&lt;/span&gt; b.Add(2.0);&lt;/pre&gt;
&lt;pre style="border-style:none;margin:0em;padding:0px;overflow:visible;font-size:8pt;width:100%;color:black;line-height:12pt;"&gt;&lt;span&gt;   8:&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="border-style:none;margin:0em;padding:0px;overflow:visible;font-size:8pt;width:100%;color:black;line-height:12pt;"&gt;&lt;span&gt;   9:&lt;/span&gt; Console.WriteLine((a[0] == b[0]));&lt;/pre&gt;
&lt;pre style="border-style:none;margin:0em;padding:0px;overflow:visible;font-size:8pt;width:100%;color:black;line-height:12pt;"&gt;&lt;span&gt;  10:&lt;/span&gt; Console.WriteLine((a[1] == b[1]));&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
What will be typed into the console? And &lt;b&gt;&lt;span style="text-decoration:underline;"&gt;WHY?&lt;/span&gt;&lt;/b&gt;&lt;/blockquote&gt;

&lt;p&gt; &lt;/p&gt;

&lt;p&gt; This one is fairly trivial (They seem to be alternating between difficult and easy questions).  And, as requested, I formulated my answer before typing it into VS (actually, I copy'n'pasted in SnippetCompiler), but the compiler DID confirm the answer I'd already theorized.&lt;/p&gt;
&lt;p&gt;This answer is short enough that we can use the cool "white-on-white; select to see it" trick--- However, RSS feed (and apparently the theme of this blog) seem to ignore the color style, so it's probably visible to you below.. &lt;/p&gt;

&lt;p&gt; &lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;div style="color:white;"&gt;
&lt;p&gt;ArrayList is deep-down, just an object[].  To store an valuetype, like an int or float, in an ArrayList, that value would first have to be boxed.  Each valuetype is boxed separately, in distinct objects, even if they do happen to have the same value. When we get to the WriteLines, we are just performing (object) == (object) (actually, Object.ReferenceEquals(object1, object2); )  ReferenceEquals knows nothing about unboxing.  It just asks, "Are these two references pointing to the exact same object?".  For any two boxed objects, regardless of their value, the answer would be "No".  Hence, both lines print "False".&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt; &lt;/p&gt;

&lt;p&gt; (select the blank space above)&lt;/p&gt;
&lt;br /&gt;
&lt;div class = "shareblock"&gt;&lt;strong&gt;Share this post:&lt;/strong&gt; &lt;a title="Email DEV102%27s+Programming+Job+Interview+Challenge+%236+" href = "mailto:?body=Thought you might like this: http://honestillusion.com/blogs/blog_0/archive/2008/06/02/dev102-s-programming-job-interview-challenge-6.aspx&amp;subject=DEV102%27s+Programming+Job+Interview+Challenge+%236+"&gt;Email it!&lt;/a&gt; | &lt;a href = "http://del.icio.us/post?url=http://honestillusion.com/blogs/blog_0/archive/2008/06/02/dev102-s-programming-job-interview-challenge-6.aspx&amp;title=DEV102%27s+Programming+Job+Interview+Challenge+%236+" title="Submit DEV102%27s+Programming+Job+Interview+Challenge+%236+ to del.icio.us" &gt;bookmark it!&lt;/a&gt; | &lt;a href = "http://www.digg.com/submit?url=http://honestillusion.com/blogs/blog_0/archive/2008/06/02/dev102-s-programming-job-interview-challenge-6.aspx&amp;phase=2" title="Submit DEV102%27s+Programming+Job+Interview+Challenge+%236+ to digg.com"&gt;digg it!&lt;/a&gt; | &lt;a href = "http://reddit.com/submit?url=http://honestillusion.com/blogs/blog_0/archive/2008/06/02/dev102-s-programming-job-interview-challenge-6.aspx&amp;title=DEV102%27s+Programming+Job+Interview+Challenge+%236+" title="Submit DEV102%27s+Programming+Job+Interview+Challenge+%236+ to reddit.com"&gt;reddit!&lt;/a&gt;&lt;/div&gt;&lt;img src="http://honestillusion.com/aggbug.aspx?PostID=4914" width="1" height="1"&gt;</description><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/Code/default.aspx">Code</category><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/.Net/default.aspx">.Net</category><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/dotnet/default.aspx">dotnet</category><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/csharp/default.aspx">csharp</category></item><item><title>DEV102's Programming Job Interview Challenge #5</title><link>http://honestillusion.com/blogs/blog_0/archive/2008/05/26/dev102-s-programming-job-interview-challenge-5.aspx</link><pubDate>Mon, 26 May 2008 12:57:20 GMT</pubDate><guid isPermaLink="false">0c240a87-1bdc-4d60-96f7-7d0531c1460e:4825</guid><dc:creator>James</dc:creator><slash:comments>0</slash:comments><description>
  &lt;p&gt;DEV102 announced the &lt;a href="http://www.dev102.com/2008/05/26/a-programming-job-interview-challenge-5-records-sorting/"&gt;correct responses to last weeks challenge&lt;/a&gt; today.  Since I announced in my blog I got a prominent spot in their post, which is good considering I was one of about 10,000 correct answers and I gave it rather late in the process.  Hopefully, I can improve on both those areas this week.&lt;/p&gt;  &lt;p&gt;Two other things they messages showed.  1) It apparently takes a lot of hunting on this blog to figure out my name (&lt;strong&gt;James Curran&lt;/strong&gt;), and 2) They like it if you hide the solution with HTML tricks.  Unfortunately, while last week's answer was three simple lines of code, this week's so going to be too long to do that effectively.&lt;/p&gt;  &lt;p&gt;Anyway, on to &lt;a href="http://www.dev102.com/2008/05/26/a-programming-job-interview-challenge-5-records-sorting/"&gt;this week's puzzle&lt;/a&gt;:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;em&gt;You are asked to sort a collection of records. The records are stored in a file on the disk, and the size of the file is much bigger than available memory you can work with. Assume a record size is 10 bytes and file size is 1GB. you read and write data to/from disk in units of pages where each page is 1KB big. You have few (less than 10) available pages of physical memory. Assume you are given a method to compare two records.&lt;/em&gt;&lt;/p&gt;    &lt;p&gt;&lt;em&gt;How can you sort the records under the described conditions?&lt;/em&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;The trick here is to do lots of merge sorts, but we get to that in a minute.  But first to prepare, we have to sort each page, hence, read one page, and sort it's records in memory.  Exactly how it's sorted is irrelevant. A page only has 100 10-byte records so Quicksort is probably overkill -- an Insertion sort is probably best. Then that page is written back to the file in place, and we more to the next one.&lt;/p&gt;  &lt;p&gt;When we finish sorting each page individually, then we begin the Mergesort.  Read two pages and merge them by comparing the first items in each list.  Once the new list fills a page, it's written to a new file.  Repeat this, and eventually, you have half as many segments, each two pages long. Then, do it all over again, merging two-page segments into four page segment.  The trick is, since the two-page segments are already sorted, they can be read in one page at a time, and the output can be written to disk as soon as a page is filled.&lt;/p&gt;  &lt;p&gt;Keep repeating the process, merge four-page segment into eight-page segments, 8-pages into 16-page, etc.  Eventually you will be merging two 512-page segments, and you're done.&lt;/p&gt;  &lt;p&gt;The process own requires three pages of physical memory, and we have a bit more, so some optimizing can be done, but that's essentially it.&lt;/p&gt;
&lt;div class = "shareblock"&gt;&lt;strong&gt;Share this post:&lt;/strong&gt; &lt;a title="Email DEV102%27s+Programming+Job+Interview+Challenge+%235" href = "mailto:?body=Thought you might like this: http://honestillusion.com/blogs/blog_0/archive/2008/05/26/dev102-s-programming-job-interview-challenge-5.aspx&amp;subject=DEV102%27s+Programming+Job+Interview+Challenge+%235"&gt;Email it!&lt;/a&gt; | &lt;a href = "http://del.icio.us/post?url=http://honestillusion.com/blogs/blog_0/archive/2008/05/26/dev102-s-programming-job-interview-challenge-5.aspx&amp;title=DEV102%27s+Programming+Job+Interview+Challenge+%235" title="Submit DEV102%27s+Programming+Job+Interview+Challenge+%235 to del.icio.us" &gt;bookmark it!&lt;/a&gt; | &lt;a href = "http://www.digg.com/submit?url=http://honestillusion.com/blogs/blog_0/archive/2008/05/26/dev102-s-programming-job-interview-challenge-5.aspx&amp;phase=2" title="Submit DEV102%27s+Programming+Job+Interview+Challenge+%235 to digg.com"&gt;digg it!&lt;/a&gt; | &lt;a href = "http://reddit.com/submit?url=http://honestillusion.com/blogs/blog_0/archive/2008/05/26/dev102-s-programming-job-interview-challenge-5.aspx&amp;title=DEV102%27s+Programming+Job+Interview+Challenge+%235" title="Submit DEV102%27s+Programming+Job+Interview+Challenge+%235 to reddit.com"&gt;reddit!&lt;/a&gt;&lt;/div&gt;&lt;img src="http://honestillusion.com/aggbug.aspx?PostID=4825" width="1" height="1"&gt;</description></item><item><title>DEV102's Programming Job Interview Challenge #4</title><link>http://honestillusion.com/blogs/blog_0/archive/2008/05/23/dev102-s-programming-job-interview-challenge-4.aspx</link><pubDate>Fri, 23 May 2008 13:58:31 GMT</pubDate><guid isPermaLink="false">0c240a87-1bdc-4d60-96f7-7d0531c1460e:4766</guid><dc:creator>James</dc:creator><slash:comments>1</slash:comments><description>
  &lt;p&gt;The folks at Dev102.com are offering weekly programming challenges, where they offer questions, and let bloggers post about them.  I meant to write an answer for last week, but never got around to it.  Just as well -- my answer would have been wrong.  SO, let's move on to &lt;a href="http://www.dev102.com/2008/05/19/a-programming-job-interview-challenge-4/"&gt;this week's&lt;/a&gt;:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;em&gt;How would you implement the following method: Foo(7) == 17 and Foo(17) == 7. Any other input to that method is not defined so you can return anything you want. Just follow those rules:&lt;/em&gt;&lt;/p&gt;    &lt;ul&gt;     &lt;li&gt;&lt;em&gt;Conditional statements (if, switch, …) are not allowed. &lt;/em&gt;&lt;/li&gt;      &lt;li&gt;&lt;em&gt;Usage of containers (hash tables, arrays, …) are not allowed. &lt;/em&gt;&lt;/li&gt;   &lt;/ul&gt; &lt;/blockquote&gt;  &lt;p&gt;My first thought was, since we can't use conditional statements, to use conditional &lt;em&gt;expressions&lt;/em&gt; instead:&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New"&gt;int foo(int n)      &lt;br /&gt;{      &lt;br /&gt;    return (n==7) ? 17 : (n==17) ? 7 : n;      &lt;br /&gt;} &lt;/font&gt;&lt;/p&gt;  &lt;p&gt; &lt;/p&gt;  &lt;p&gt;But clearly, that is just cheating.  (And, besides, it turns out, it's not the best solution).&lt;/p&gt;  &lt;p&gt;My next attempt was to use subtraction to create factors of zero.&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New"&gt;int foo(int n)      &lt;br /&gt;{      &lt;br /&gt;    return n + (10 * (n-17) * (n-6)) + (-10 * (n-16) * (n-7))  ;      &lt;br /&gt;} &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;There may be a formula in there that works, but that one doesn't, and before I found it, I stumble upon the &lt;em&gt;correct &lt;/em&gt;solution, which was just sitting there staring me in the face:&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New"&gt;int foo(int n)      &lt;br /&gt;{      &lt;br /&gt;    return 24-n;      &lt;br /&gt;} &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New"&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;Yep, it's just that simple.&lt;/p&gt;
&lt;div class = "shareblock"&gt;&lt;strong&gt;Share this post:&lt;/strong&gt; &lt;a title="Email DEV102%27s+Programming+Job+Interview+Challenge+%234" href = "mailto:?body=Thought you might like this: http://honestillusion.com/blogs/blog_0/archive/2008/05/23/dev102-s-programming-job-interview-challenge-4.aspx&amp;subject=DEV102%27s+Programming+Job+Interview+Challenge+%234"&gt;Email it!&lt;/a&gt; | &lt;a href = "http://del.icio.us/post?url=http://honestillusion.com/blogs/blog_0/archive/2008/05/23/dev102-s-programming-job-interview-challenge-4.aspx&amp;title=DEV102%27s+Programming+Job+Interview+Challenge+%234" title="Submit DEV102%27s+Programming+Job+Interview+Challenge+%234 to del.icio.us" &gt;bookmark it!&lt;/a&gt; | &lt;a href = "http://www.digg.com/submit?url=http://honestillusion.com/blogs/blog_0/archive/2008/05/23/dev102-s-programming-job-interview-challenge-4.aspx&amp;phase=2" title="Submit DEV102%27s+Programming+Job+Interview+Challenge+%234 to digg.com"&gt;digg it!&lt;/a&gt; | &lt;a href = "http://reddit.com/submit?url=http://honestillusion.com/blogs/blog_0/archive/2008/05/23/dev102-s-programming-job-interview-challenge-4.aspx&amp;title=DEV102%27s+Programming+Job+Interview+Challenge+%234" title="Submit DEV102%27s+Programming+Job+Interview+Challenge+%234 to reddit.com"&gt;reddit!&lt;/a&gt;&lt;/div&gt;&lt;img src="http://honestillusion.com/aggbug.aspx?PostID=4766" width="1" height="1"&gt;</description><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/Code/default.aspx">Code</category><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/.Net/default.aspx">.Net</category><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/Programming/default.aspx">Programming</category><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/dotnet/default.aspx">dotnet</category><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/csharp/default.aspx">csharp</category></item><item><title>The Need for Common Search Keywords.</title><link>http://honestillusion.com/blogs/blog_0/archive/2008/04/18/the-need-for-common-search-keywords.aspx</link><pubDate>Sat, 19 Apr 2008 00:01:10 GMT</pubDate><guid isPermaLink="false">0c240a87-1bdc-4d60-96f7-7d0531c1460e:4702</guid><dc:creator>James</dc:creator><slash:comments>1</slash:comments><description>
  &lt;p&gt;if you ever tried to Google something like "how to write a linked list in C#" you may have noticed a problem.  Most search engines have trouble dealing with the pound sign (hash/number sign/octothorpe).  You run into the same problem search for information on ".Net" or "COM" or, for that matter, "Word" or "Access".  &lt;/p&gt;  &lt;p&gt;I hit upon a similar problem a few years ago.  I was trying to set up Microsoft Money to access my bank accounts online.  I went to my banks' websites, but had trouble finding the setup instructions.  Searching a bank's website for "Money" provides many false hits.  Searching for "Microsoft" isn't much better, when every page's footer contains "Best view on Microsoft Internet Explorer 2.0 or later".  Finally, I hit upon the trick:  I searched the site for "Quicken".  The instruction for Microsoft Money were always on the same page as the instruction for Quicken.&lt;/p&gt;  &lt;p&gt;This lead to to the idea to solve the problem I mentioned up top.  Basically, for very technology or product with an inconvenient name, we need a standard searchable keyword, so that whenever someone writes a blog post about a C# topic, if he includes the "csharp" keyword, then someone searching on "csharp" will be able to find it.  Of course, there's two problems with this: first we have to get bloggers to use the keywords and then we have to make sure the seekers know enough to use them.&lt;/p&gt;  &lt;p&gt;Last night I was at a .Net (dotnet) users' group meeting where some folks from MSDN (the website) were soliciting suggestions on improvements.  I presented this suggestion to them, and they were receptive to it, but it really isn't MSDN targeted at them.  The real solution would be to be a list of officially sanctioned keywords coming direct from Microsoft and  promoted by them (so that banks know to put "msmoney" on a page that described the setup for Microsoft Money.&lt;/p&gt;  &lt;p&gt;But in the mean time, I figured I could leverage some of the blogosphere to help push this idea along. &lt;/p&gt;  &lt;p&gt;So, let's start defining the ground rules.&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;A keyword needs to be a single term ("csharp", not "c sharp") &lt;/li&gt;    &lt;li&gt;A keyword needs to uniquely (or very close to it) indicate the subject ("msword", not "word") (If your spell-checker says it's misspelled, that's a good sign) &lt;/li&gt;    &lt;li&gt;A keyword should be a string that is decipherable when written as one word in all lowercase. (so we don't run into the problem of "expertsexchange") &lt;/li&gt;    &lt;li&gt;Unfortunately, there are probably trademark issues to deal with (Microsoft will probably want it to be "microsoftword" instead of "msword") &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;So, to start us off, here are a few I thought up.  Be sure to include them in any blog post (in the body or tags or header) on the subject.&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;"C#" = "csharp" &lt;/li&gt;    &lt;li&gt;"C++" = "cplusplus" &lt;/li&gt;    &lt;li&gt;".Net" = "dotnet" &lt;/li&gt;    &lt;li&gt;"ASP.NET" = "aspnet"  (or should we go for "aspdotnet"?) &lt;/li&gt;    &lt;li&gt;"ASP.NET Ajax" = "aspnetajax" &lt;/li&gt;    &lt;li&gt;"LINQ" = "linq" (that was easy -- maybe Microsoft is learning). &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt; &lt;/p&gt; &lt;a href="http://www.dotnetkicks.com/kick/?url=http%3a%2f%2fhonestillusion.com%2fblogs%2fblog_0%2farchive%2f2008%2f04%2f18%2fthe-need-for-common-search-keywords.aspx"&gt;&lt;img alt="kick it on DotNetKicks.com" src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fhonestillusion.com%2fblogs%2fblog_0%2farchive%2f2008%2f04%2f18%2fthe-need-for-common-search-keywords.aspx" border="0" /&gt;&lt;/a&gt;
&lt;div class = "shareblock"&gt;&lt;strong&gt;Share this post:&lt;/strong&gt; &lt;a title="Email The+Need+for+Common+Search+Keywords." href = "mailto:?body=Thought you might like this: http://honestillusion.com/blogs/blog_0/archive/2008/04/18/the-need-for-common-search-keywords.aspx&amp;subject=The+Need+for+Common+Search+Keywords."&gt;Email it!&lt;/a&gt; | &lt;a href = "http://del.icio.us/post?url=http://honestillusion.com/blogs/blog_0/archive/2008/04/18/the-need-for-common-search-keywords.aspx&amp;title=The+Need+for+Common+Search+Keywords." title="Submit The+Need+for+Common+Search+Keywords. to del.icio.us" &gt;bookmark it!&lt;/a&gt; | &lt;a href = "http://www.digg.com/submit?url=http://honestillusion.com/blogs/blog_0/archive/2008/04/18/the-need-for-common-search-keywords.aspx&amp;phase=2" title="Submit The+Need+for+Common+Search+Keywords. to digg.com"&gt;digg it!&lt;/a&gt; | &lt;a href = "http://reddit.com/submit?url=http://honestillusion.com/blogs/blog_0/archive/2008/04/18/the-need-for-common-search-keywords.aspx&amp;title=The+Need+for+Common+Search+Keywords." title="Submit The+Need+for+Common+Search+Keywords. to reddit.com"&gt;reddit!&lt;/a&gt;&lt;/div&gt;&lt;img src="http://honestillusion.com/aggbug.aspx?PostID=4702" width="1" height="1"&gt;</description></item><item><title>How can I easily log a message to a file for debugging purposes?</title><link>http://honestillusion.com/blogs/blog_0/archive/2008/04/16/how-can-i-easily-log-a-message-to-a-file-for-debugging-purposes.aspx</link><pubDate>Wed, 16 Apr 2008 14:06:47 GMT</pubDate><guid isPermaLink="false">0c240a87-1bdc-4d60-96f7-7d0531c1460e:4660</guid><dc:creator>James</dc:creator><slash:comments>0</slash:comments><description>
  &lt;p&gt;Today, either Bloglines.com or blogs.MSDN.com blinked, and suddenly I'm seeing old entries on the 'C# Frequently Asked Questions' blog as new.  No one has posted anything there in over two years. &lt;/p&gt; &lt;p&gt;Anyway, reading the most recent message, it offered a method for logging a message.  Now, ignoring side debates over log4net vs nLog vs. the Event log vs. Trace, and just concentrating on the code post --- It's not very good.  Look for yourself (then come back here)  &lt;a title="http://blogs.msdn.com/csharpfaq/archive/2006/03/27/562555.aspx" href="http://blogs.msdn.com/csharpfaq/archive/2006/03/27/562555.aspx"&gt;http://blogs.msdn.com/csharpfaq/archive/2006/03/27/562555.aspx&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Despite being written by a C# MVP (*), it shows a lack of understanding of basic .Net library features, and well as C#.  So, I figured, I'd rewrite it.  I limited myself to taking what's there and fixing it instead of going an entirely different way (ie, log4net vs nLog vs etc).  Here's the revised code:&lt;/p&gt; &lt;div class="csharpcode"&gt;&lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System.IO;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; LogMessageToFile(&lt;span class="kwrd"&gt;string&lt;/span&gt; msg)&lt;/pre&gt;&lt;pre&gt;{&lt;/pre&gt;&lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;string&lt;/span&gt; logFilepath = Path.Combine(Environment.GetEnvironmentVariable(&lt;span class="str"&gt;"TEMP"&lt;/span&gt;),&lt;span class="str"&gt;"My Log File.txt"&lt;/span&gt;);&lt;/pre&gt;&lt;pre&gt;    &lt;span class="kwrd"&gt;using&lt;/span&gt; (StreamWriter sw = File.AppendText(logFilepath))&lt;/pre&gt;&lt;pre class="alt"&gt;    {&lt;/pre&gt;&lt;pre&gt;        &lt;span class="kwrd"&gt;string&lt;/span&gt; logLine = String.Format(&lt;span class="str"&gt;"{0:G}: {1}."&lt;/span&gt;, DateTime.Now, msg);&lt;/pre&gt;&lt;pre class="alt"&gt;        sw.WriteLine(logLine);&lt;/pre&gt;&lt;pre&gt;    }&lt;/pre&gt;&lt;pre class="alt"&gt;}&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;A few years ago, I bought a number of books, all with the title of same variation of "C# Cookbook".  Again, a lot of bad code.  I've been meaning to start a series of articles about revising them.....&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;(*) Years ago, I was one of the very first C++ MVPs.  After ten years, I was dropped from the program.  Since then I've tried to become a C# MVP, without any luck. I'm beginning to get bitter about it.  ;-)&lt;/p&gt;
&lt;div class = "shareblock"&gt;&lt;strong&gt;Share this post:&lt;/strong&gt; &lt;a title="Email How+can+I+easily+log+a+message+to+a+file+for+debugging+purposes%3f" href = "mailto:?body=Thought you might like this: http://honestillusion.com/blogs/blog_0/archive/2008/04/16/how-can-i-easily-log-a-message-to-a-file-for-debugging-purposes.aspx&amp;subject=How+can+I+easily+log+a+message+to+a+file+for+debugging+purposes%3f"&gt;Email it!&lt;/a&gt; | &lt;a href = "http://del.icio.us/post?url=http://honestillusion.com/blogs/blog_0/archive/2008/04/16/how-can-i-easily-log-a-message-to-a-file-for-debugging-purposes.aspx&amp;title=How+can+I+easily+log+a+message+to+a+file+for+debugging+purposes%3f" title="Submit How+can+I+easily+log+a+message+to+a+file+for+debugging+purposes%3f to del.icio.us" &gt;bookmark it!&lt;/a&gt; | &lt;a href = "http://www.digg.com/submit?url=http://honestillusion.com/blogs/blog_0/archive/2008/04/16/how-can-i-easily-log-a-message-to-a-file-for-debugging-purposes.aspx&amp;phase=2" title="Submit How+can+I+easily+log+a+message+to+a+file+for+debugging+purposes%3f to digg.com"&gt;digg it!&lt;/a&gt; | &lt;a href = "http://reddit.com/submit?url=http://honestillusion.com/blogs/blog_0/archive/2008/04/16/how-can-i-easily-log-a-message-to-a-file-for-debugging-purposes.aspx&amp;title=How+can+I+easily+log+a+message+to+a+file+for+debugging+purposes%3f" title="Submit How+can+I+easily+log+a+message+to+a+file+for+debugging+purposes%3f to reddit.com"&gt;reddit!&lt;/a&gt;&lt;/div&gt;&lt;img src="http://honestillusion.com/aggbug.aspx?PostID=4660" width="1" height="1"&gt;</description><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/Code/default.aspx">Code</category><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/.Net/default.aspx">.Net</category><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/Programming/default.aspx">Programming</category><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/MVP/default.aspx">MVP</category></item><item><title>Predictions</title><link>http://honestillusion.com/blogs/blog_0/archive/2008/03/25/predictions.aspx</link><pubDate>Wed, 26 Mar 2008 03:16:00 GMT</pubDate><guid isPermaLink="false">0c240a87-1bdc-4d60-96f7-7d0531c1460e:4583</guid><dc:creator>James</dc:creator><slash:comments>1</slash:comments><description>
  &lt;P&gt;My friend Chris is, like me, a staunch Democratic.  Unlike me, he's also an incredible pessimist.  In 2006, he made what he called his "optimistic" prediction for the midterm election: The democrats would gain 3 Senate seat, 10 house seats, and 3 governorships. (Actual results: Democrats gained 6 Senate seats, 30 House seats, and 6 Governors).  I didn't make any predictions then.&lt;/P&gt;
&lt;P&gt;Since another election is looming, he's made is his predictions for the elections, and in the interest of balance, I've made mine.  And, since I'm probably going to lose the napkin I wrote them down on before November, I figured I'd record them here, so I know where I can find them, after the election.&lt;/P&gt;
&lt;P&gt;So, here goes:&lt;/P&gt;
&lt;H2&gt;Chris's Predictions&lt;/H2&gt;
&lt;P&gt;Republicans will gain 8 house seats, 2 governorship while the Senate will stay the same.  McCain will become president, winning 36 states.&lt;/P&gt;
&lt;H2&gt;James's Predictions:&lt;/H2&gt;
&lt;P&gt;Democrats will gain 10 House seats, 4 Senate seats, and 2 governorships.  The democrat will win the White House, winning 20 (mostly large) states.&lt;/P&gt;
&lt;P&gt;Neither of us ventured a prediction on who will be the Democratic candidate.  Chris wants Obama, because he things he has the best chance of winning.  I want Clinton, because I think she'll be the best president.&lt;/P&gt;
&lt;div class = "shareblock"&gt;&lt;strong&gt;Share this post:&lt;/strong&gt; &lt;a title="Email Predictions" href = "mailto:?body=Thought you might like this: http://honestillusion.com/blogs/blog_0/archive/2008/03/25/predictions.aspx&amp;subject=Predictions"&gt;Email it!&lt;/a&gt; | &lt;a href = "http://del.icio.us/post?url=http://honestillusion.com/blogs/blog_0/archive/2008/03/25/predictions.aspx&amp;title=Predictions" title="Submit Predictions to del.icio.us" &gt;bookmark it!&lt;/a&gt; | &lt;a href = "http://www.digg.com/submit?url=http://honestillusion.com/blogs/blog_0/archive/2008/03/25/predictions.aspx&amp;phase=2" title="Submit Predictions to digg.com"&gt;digg it!&lt;/a&gt; | &lt;a href = "http://reddit.com/submit?url=http://honestillusion.com/blogs/blog_0/archive/2008/03/25/predictions.aspx&amp;title=Predictions" title="Submit Predictions to reddit.com"&gt;reddit!&lt;/a&gt;&lt;/div&gt;&lt;img src="http://honestillusion.com/aggbug.aspx?PostID=4583" width="1" height="1"&gt;</description></item><item><title>Joins - LINQ's critical, overlooked feature.</title><link>http://honestillusion.com/blogs/blog_0/archive/2007/12/18/joins-linq-s-critical-overlooked-feature.aspx</link><pubDate>Wed, 19 Dec 2007 01:35:00 GMT</pubDate><guid isPermaLink="false">0c240a87-1bdc-4d60-96f7-7d0531c1460e:4569</guid><dc:creator>James</dc:creator><slash:comments>1</slash:comments><description>
  &lt;p&gt;As i was planning my rewrite of NJTheater.com I looked at a couple different Object-Relationship Mappers (mostly code generators which examined a database schema and produced one class per table to read and write rows to it.  All seemed particularly lacking because of this.  Then I find LINQ, and realized that I had found exact the system I was looking for.&lt;/p&gt;  &lt;p&gt;To understand the problem, consider the main page of NJTheater.com, which on your average day looks something like this:&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;The Blue Bird (11/27/2007 - 12/31/2007)      &lt;br /&gt;by Shakespeare Theatre of New Jersey (at F.M. Kirby Theater in Madison) &lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Doubt (11/27/2007 - 12/23/2007)      &lt;br /&gt;by George Street Playhouse (at George Street Playhouse in New Brunswick) &lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Seussical: The Musical (12/1/2007 - 12/23/2007)      &lt;br /&gt;by Bergen County Players (at Little Firehouse Theatre in Oradell) &lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;The database is heavily normalized, so to retrieve that data, I need an SQL query that looks like this: &lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New"&gt;Select pl.Title, p.StartDate, p.EndDate, t.Name, v.Name, v.City      &lt;br /&gt;&lt;/font&gt;&lt;font face="Courier New"&gt;From Productions P      &lt;br /&gt;&lt;/font&gt;&lt;font face="Courier New"&gt;inner join Troupes T on p.TroupeID = t.TroupeID      &lt;br /&gt;&lt;/font&gt;&lt;font face="Courier New"&gt;inner join Venues V on p.VenueID = v.VenueID      &lt;br /&gt;&lt;/font&gt;&lt;font face="Courier New"&gt;inner join Plays pl on p.PlayID = pl.PlayID      &lt;br /&gt;&lt;/font&gt;&lt;font face="Courier New"&gt;where p. FirstDate &amp;gt;= GetDate() and p.FirstDate &amp;lt;= GetDate() + 7&lt;/font&gt;&lt;/p&gt; p&amp;gt;The actual query is a bit more complicated, but we'll go with that for now.   &lt;p&gt;That's one SQL statement which returns 3 to 30 rows (depending on the week) which holds all the data to be displayed.&lt;/p&gt;  &lt;p&gt;Which brings us to the problem.  Most ORM systems would have me translate that into something like&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New"&gt;ProductionList productions = db.Productions.WhereBetween("StartDate", datetime.Now, DateTime.Now.AddDay(7));&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;And then use it like this:&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New"&gt;foreach (Production prod in productions)      &lt;br /&gt;     Print prod.Play.Title +" ( " +prod.StartDate + " - " + prod.EndDate + ")"       &lt;br /&gt;     Print "by " + prod.Troupe.Name " (at " + prod.Venue.Name + " in "+ prod.Venue.City +")"&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;(I made that syntax up, but it's fairly typical.)&lt;/p&gt;  &lt;p&gt;Which brings us to the problem.  The first line would generate one SQL query  which would look something like this:&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New"&gt;Select p.*      &lt;br /&gt;&lt;/font&gt;&lt;font face="Courier New"&gt;From Productions P      &lt;br /&gt;&lt;/font&gt;&lt;font face="Courier New"&gt;where p. FirstDate &amp;gt;= GetDate() and p.FirstDate &amp;lt;= GetDate() + 7&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;and would return about 15 records.  However, when it goes into the loop to render the actual page, then we sudden have a lot more SQL queries:&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New"&gt;Select title from play where playid = 123;      &lt;br /&gt;select name from troupe where troupeid=131;       &lt;br /&gt;select name, city  from venue where venueid=102;&lt;/font&gt;&lt;/p&gt; &lt;font face="Courier New"&gt;Select title from play where playid = 143;    &lt;br /&gt;select name from troupe where troupeid=134;     &lt;br /&gt;select name, city  from venue where venueid=202;&lt;/font&gt;   &lt;p&gt;etc etc.  We go from one query returning N rows, to 3N+1 queries.  We've just massively increased the amount of work needed to be done to render the front (and most popular)page on the web site.&lt;/p&gt;  &lt;p&gt;Which brings us back to LINQ.    The LINQ query I use is:&lt;/p&gt;  &lt;p&gt;var productions = from prod in db.Productions    &lt;br /&gt;        where prod.StartDate &amp;lt; DateTime.Now.AddDays(7)     &lt;br /&gt;        &amp;amp;&amp;amp; prod.StartDate &amp;gt; DateTime.Now     &lt;br /&gt;        orderby prod.Play.Title     &lt;br /&gt;        select new  &lt;br /&gt;               {     &lt;br /&gt;                   Title = prod.Play.Title,     &lt;br /&gt;                   Troupe = prod.Troupe.Name,     &lt;br /&gt;                   Venue = prod.Venue.Name,     &lt;br /&gt;                   City = prod.Venue.City,     &lt;br /&gt;                   StartDate = prod.StartDate ,     &lt;br /&gt;                   EndDate = prod.EndDate &lt;/p&gt;  &lt;p&gt;               };&lt;/p&gt; &lt;font face="Courier New"&gt;foreach (Production prod in productions)    &lt;br /&gt;     Print prod.Title +" ( " +prod.StartDate + " - " + prod.EndDate + ")"     &lt;br /&gt;     Print "by " + prod.Troupe " (at " + prod.Venue + " in "+ prod.City +")"&lt;/font&gt;   &lt;p&gt;The first thing you should notice is that except for the verbose select clause, this syntax is rather close to the one for my theoretic ORM.&lt;/p&gt;  &lt;p&gt;A more subtle difference is that I've slipped in a orderby based on one of the JOINs, which I'm not sure how I'd  do in the ORM.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;But the most important thing you should notice is that this will produce a single SQL statement, one that is virtual identical to the hand-crafted one I started this article with.&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;font face="ver"&gt;If you don't believe me, here's output from LINQPad:&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;SELECT [t].[Title], [t2].[ Name ] AS [Troupe], [t3].[ Name ] AS [Venue], [t3].[City],    &lt;br /&gt;       [t0].[FirstPerformance] AS [StartDate], [t0].[LastPerformance] AS [EndDate]     &lt;br /&gt;FROM [Productions] AS [t0]     &lt;br /&gt;INNER JOIN [Plays] AS [t1] ON [t1].[PlayID] = [t0].[PlayID]     &lt;br /&gt;INNER JOIN [Troupes] AS [t2] ON [t2].[TroupeID] = [t0].[TroupeID]     &lt;br /&gt;LEFT OUTER JOIN [Venues] AS [t3] ON [t3].[VenueID] = [t0].[VenueID]     &lt;br /&gt;WHERE ([t0].[FirstPerformance] &amp;lt; @p0) AND ([t0].[LastPerformance] &amp;gt; @p1)     &lt;br /&gt;ORDER BY [t1].[Title]     &lt;br /&gt;    &lt;br /&gt;-- @p0: Input DateTime (Size = 0; Prec = 0; Scale = 0) [12/25/2007 7:00:54 PM]     &lt;br /&gt;-- @p1: Input DateTime (Size = 0; Prec = 0; Scale = 0) [12/18/2007 7:00:54 PM]     &lt;br /&gt;-- Context: SqlProvider(Sql2005) Model: AttributedMetaModel Build: 3.5.21022.8     &lt;br /&gt;&lt;/p&gt; &lt;a href="http://www.dotnetkicks.com/kick/?url=http%3a%2f%2fhonestillusion.com%2fblogs%2fblog_0%2farchive%2f2007%2f12%2f18%2fjoins-linq-s-critical-overlooked-feature.aspx"&gt;&lt;img alt="kick it on DotNetKicks.com" src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fhonestillusion.com%2fblogs%2fblog_0%2farchive%2f2007%2f12%2f18%2fjoins-linq-s-critical-overlooked-feature.aspx" border="0" /&gt;&lt;/a&gt;
&lt;div class = "shareblock"&gt;&lt;strong&gt;Share this post:&lt;/strong&gt; &lt;a title="Email Joins+-+LINQ%27s+critical%2c+overlooked+feature." href = "mailto:?body=Thought you might like this: http://honestillusion.com/blogs/blog_0/archive/2007/12/18/joins-linq-s-critical-overlooked-feature.aspx&amp;subject=Joins+-+LINQ%27s+critical%2c+overlooked+feature."&gt;Email it!&lt;/a&gt; | &lt;a href = "http://del.icio.us/post?url=http://honestillusion.com/blogs/blog_0/archive/2007/12/18/joins-linq-s-critical-overlooked-feature.aspx&amp;title=Joins+-+LINQ%27s+critical%2c+overlooked+feature." title="Submit Joins+-+LINQ%27s+critical%2c+overlooked+feature. to del.icio.us" &gt;bookmark it!&lt;/a&gt; | &lt;a href = "http://www.digg.com/submit?url=http://honestillusion.com/blogs/blog_0/archive/2007/12/18/joins-linq-s-critical-overlooked-feature.aspx&amp;phase=2" title="Submit Joins+-+LINQ%27s+critical%2c+overlooked+feature. to digg.com"&gt;digg it!&lt;/a&gt; | &lt;a href = "http://reddit.com/submit?url=http://honestillusion.com/blogs/blog_0/archive/2007/12/18/joins-linq-s-critical-overlooked-feature.aspx&amp;title=Joins+-+LINQ%27s+critical%2c+overlooked+feature." title="Submit Joins+-+LINQ%27s+critical%2c+overlooked+feature. to reddit.com"&gt;reddit!&lt;/a&gt;&lt;/div&gt;&lt;img src="http://honestillusion.com/aggbug.aspx?PostID=4569" width="1" height="1"&gt;</description></item><item><title>My Second CodePlex Project : State Theater</title><link>http://honestillusion.com/blogs/blog_0/archive/2007/12/17/my-second-codeplex-project-state-theater.aspx</link><pubDate>Mon, 17 Dec 2007 17:35:09 GMT</pubDate><guid isPermaLink="false">0c240a87-1bdc-4d60-96f7-7d0531c1460e:4568</guid><dc:creator>James</dc:creator><slash:comments>0</slash:comments><description>
  &lt;p&gt;Well, as I promised months ago, I've created my second CodePlex project.  Actually, I created months ago, while this site was down (as the artist I am, I think I'll refer to that as it's "black period"), But now that I'm back, I guess it's time to make a formal announcement.&lt;/p&gt; &lt;p&gt;The &lt;a href="http://www.codeplex.com/StateTheater" target="_blank"&gt;State Theater Project&lt;/a&gt; is my attempt to completely rewrite my main web site (&lt;a href="http://www.njtheater.com"&gt;www.njtheater.com&lt;/a&gt;).  The original (still at that web address for now) was written by me, mostly 10 years ago, in classic ASP.   The ASP pages are almost purely presentational -- they just read stuff from the database and display it on the screen, using a lot of questionable techniques (in some spots, I was formatting HTML in SQL select statements)&lt;/p&gt; &lt;p&gt;I added a few pages "recently" (i.e. within the last five years) in C#/ASP.NET.  These were interactive, and mostly hidden from view of most users.  Only registered users having certain roles saw them, and those pages allow those users to enter updates directly into the web site's database.&lt;/p&gt; &lt;p&gt;However, most of the theater companies just emailed the details of the shows, and hoped I found time to enter them.  (Especially, since most of the important info can't be entered via the web pages, so only I could do it).&lt;/p&gt; &lt;p&gt;The main problem is that I needed a Ajax-based drop-down listbox, because the database is heavily normalized, so when someone entered "William Shakespeare", I needed to know they really meant Person ID#74.  &lt;/p&gt; &lt;p&gt;Some years ago I paid good cash for one such control, which allowed me to get the few pages working that I did.  But it was rather limited (I still don't think it works with Firefox) and has a spotty update &amp;amp; support history and in general wasn't letting me advance.  When the Ajax craze start two years ago, a number of new, better and &lt;strong&gt;free&lt;/strong&gt; DDL controls became available, so I started to look into a new approach.&lt;/p&gt; &lt;p&gt;Originally, I planned on a complete ASP.NET approach, and started to work on that in the spring of 2006.  The first problem I had was my membership/roles data.  Membership was based on the FORUM_MEMBER table from Snitz Forums, which I had been using for the Forums section of the site.  &lt;/p&gt; &lt;p&gt;Now, Snitz is a fine forums packages, but it's also Classic ASP, but is getting kinda old -- it hasn't had a major update in year, and in fact, has had only two minor updates (most fixing security breaches) in the last 2 1/2 years.  But mostly, the problem with it is that it's membership system was intended to be used strictly for the forums themselves, and any allowance for it to be used as a general web site membership subsystem were clearly an afterthought.&lt;/p&gt; &lt;p&gt;What I wanted to do was to use the ASP.NET membership system that came with v2.0.  The trouble here was that Snitz stored passwords as a one-way hash.  There is no way to convert them back into the original password.  Which means that there's no way to more the account to the new database structure.  I'd have to assign new passwords to my 2000+ users.  That's wasn't workable.&lt;/p&gt; &lt;p&gt;Ah, but the ASP.NET membership system works on the provider model.  The SqlMembershipProvider that comes with 2.0 is just one example.  I could just write my own provider which used the existing table structure as a backing store.  I began this project in the summer of 2006. &lt;/p&gt; &lt;p&gt;The next problem was my laptop.  I was doing most of the work my lunch hour and one the train to &amp;amp; from work.  But my laptop was excessively old. (It was three years old when I bought it on eBay, and that was three years earlier).  It was taking much of the train trip just to awake from hibernation. I was just days away from buying a brand-spanking new laptop when I completely new problem arose -- I was laid off from my job.&lt;/p&gt; &lt;p&gt;Now, I bounced back from that fairly quickly --- but the time out of work chewed up the saving I was planning on using to buy the laptop--- but the new job gave me a laptop --- but the new job took away train ride to work (I had to drive there), and because I was consulting, I had to take short lunches.&lt;/p&gt; &lt;p&gt;Anyway, seven months later, that contract ended, and a new one began -- back on the train to NYC, and this time it was one long ride instead of two short ones, so I could get more done.  After a few weeks of saving, I finally got that new laptop, and I could finally complete the SnitzMembershipProvider which became the first CodePlex project, only a year after I had started it.&lt;/p&gt; &lt;p&gt;And so then I finally began the work on revising the web site. But, by this time, I'd become fascinated with &lt;a href="http://www.castleproject.org/monorail" target="_blank"&gt;Castle Monorail&lt;/a&gt; and LINQ, and decided to try those for the web site.   Plus, as much of the graphic design was mixed with the code, I tried for a more generic, skinnable approach of putting everything in &amp;lt;DIV&amp;gt;s and using CSS for styling it.  Finally, I'm trying to make it generic enough so that some other group in a different state could take the code and create there own similar web site for their state -- with a completely different look, just by changing the CSS file.&lt;/p&gt; &lt;p&gt;For the Ajax work, and pretty much all the interactive forms, I'm using the &lt;a href="http://extjs.com/" target="_blank"&gt;Ext.Js&lt;/a&gt; library, except for large textboxes, for which I'm using &lt;a href="http://tinymce.moxiecode.com/" target="_blank"&gt;TinyMCE&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;You can see what I've done so far as &lt;a href="http://www.NJTheater.org"&gt;www.NJTheater.org&lt;/a&gt;.&lt;/p&gt;
&lt;div class = "shareblock"&gt;&lt;strong&gt;Share this post:&lt;/strong&gt; &lt;a title="Email My+Second+CodePlex+Project+%3a+State+Theater" href = "mailto:?body=Thought you might like this: http://honestillusion.com/blogs/blog_0/archive/2007/12/17/my-second-codeplex-project-state-theater.aspx&amp;subject=My+Second+CodePlex+Project+%3a+State+Theater"&gt;Email it!&lt;/a&gt; | &lt;a href = "http://del.icio.us/post?url=http://honestillusion.com/blogs/blog_0/archive/2007/12/17/my-second-codeplex-project-state-theater.aspx&amp;title=My+Second+CodePlex+Project+%3a+State+Theater" title="Submit My+Second+CodePlex+Project+%3a+State+Theater to del.icio.us" &gt;bookmark it!&lt;/a&gt; | &lt;a href = "http://www.digg.com/submit?url=http://honestillusion.com/blogs/blog_0/archive/2007/12/17/my-second-codeplex-project-state-theater.aspx&amp;phase=2" title="Submit My+Second+CodePlex+Project+%3a+State+Theater to digg.com"&gt;digg it!&lt;/a&gt; | &lt;a href = "http://reddit.com/submit?url=http://honestillusion.com/blogs/blog_0/archive/2007/12/17/my-second-codeplex-project-state-theater.aspx&amp;title=My+Second+CodePlex+Project+%3a+State+Theater" title="Submit My+Second+CodePlex+Project+%3a+State+Theater to reddit.com"&gt;reddit!&lt;/a&gt;&lt;/div&gt;&lt;img src="http://honestillusion.com/aggbug.aspx?PostID=4568" width="1" height="1"&gt;</description></item><item><title>Oh My God! It's back!</title><link>http://honestillusion.com/blogs/blog_0/archive/2007/12/04/oh-my-god-it-s-back.aspx</link><pubDate>Tue, 04 Dec 2007 20:40:09 GMT</pubDate><guid isPermaLink="false">0c240a87-1bdc-4d60-96f7-7d0531c1460e:4567</guid><dc:creator>James</dc:creator><slash:comments>0</slash:comments><description>
  &lt;p&gt;Yes, after about 5 months of downtime, I finally was able to restore my blog.&lt;/p&gt; &lt;p&gt;What happened was, sometime mid-July, the PC that was running Sql Server on my network died.  It was acting funny for a few weeks, so I took it off line.  I removed the hard disk from it and attempted to install it on a different machine.  It worked OK as a second drive, but I couldn't boot from it.  At this point, I should have just left it as a second drive, but I didn't....&lt;/p&gt; &lt;p&gt;I tried re-installing Windows on that drive, and as I was doing this, the second PC failed.  That PC was my Internet gateway, so it was imperative that I get that one back online.  I shuffled disks around a bit, and got it working again.&lt;/p&gt; &lt;p&gt;Map of PCs:&lt;/p&gt; &lt;p&gt;pcA - Internet Gateway  (old Compaq, circa 2001)&lt;/p&gt; &lt;p&gt;pcB - Sql Server 2000  (identical old Compaq)&lt;/p&gt; &lt;p&gt;pcC - Sql Server 2005 (more recent generic PC, circa 2004)&lt;/p&gt; &lt;p&gt;pcD - Web server (Micron PC, circa 2002)&lt;/p&gt; &lt;p&gt;pcE - Work machine (generic PC, circa 2006)&lt;/p&gt; &lt;p&gt;pcF - HomeServer Beta 2 (generic PC, circa 2007)&lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt;Now, pcB had been decommissioned, by was still was on the table with the others. pcC died, which is why the blog went down.   I tried moving the disk to pcA, which then proceeded to die itself.  I move the system disk from pcA to pcB to regain access to the Internet.  (Complication -- they had different NIC cards).  I then had to install the other apps that were running on pcC (notably my mail server). In midst of all this disk swapping, twice I forgot to power down the PC before pulled &amp;amp; reattaching a ribbon cable to a disk -- which killed the disks, one of which was the system disk to pcC.&lt;/p&gt; &lt;p&gt;So, all I needed to do now was to restore the back up of pcC from HomeServer onto a new hard disk.  pcA seemed to recover and I bought a new HD at a computer show, so, mid-August, you would think I was good to go.  No such luck.  HomeServer refused to restore the disk.  Which was crazy, as I had already restore that disk a few weeks earlier -- You'll recall that I said that pcC had been flaky for a while; one of those acts of flakiness was crashing it's hard disk.&lt;/p&gt; &lt;p&gt;One bought a new PC, which we'll call pcG (Woot.com had a close-out for $250).  HomeServer refused to restore to that machine either.   Finally, I had an idea: I put a disk back into pcC, and boot up HomeServer's restore disk on that.  This time it would restore the disk.  I then quickly copied the database files off it. (The website is now being run off SqlServer Express on pcD, which means beside reducing the number of mission-critical PCs from two to one, the setup is now finally LEGAL).&lt;/p&gt; &lt;p&gt;In the coming days, I plan on installing HomeServer RTM on pcF, and decommission my pcG (or at least salvage the most of the hard disks from it, for the new HomeServer).  I'm not sure what pcG's eventual use will be, but I'm happy just to be back to square one.&lt;/p&gt;
&lt;div class = "shareblock"&gt;&lt;strong&gt;Share this post:&lt;/strong&gt; &lt;a title="Email Oh+My+God!+It%27s+back!" href = "mailto:?body=Thought you might like this: http://honestillusion.com/blogs/blog_0/archive/2007/12/04/oh-my-god-it-s-back.aspx&amp;subject=Oh+My+God!+It%27s+back!"&gt;Email it!&lt;/a&gt; | &lt;a href = "http://del.icio.us/post?url=http://honestillusion.com/blogs/blog_0/archive/2007/12/04/oh-my-god-it-s-back.aspx&amp;title=Oh+My+God!+It%27s+back!" title="Submit Oh+My+God!+It%27s+back! to del.icio.us" &gt;bookmark it!&lt;/a&gt; | &lt;a href = "http://www.digg.com/submit?url=http://honestillusion.com/blogs/blog_0/archive/2007/12/04/oh-my-god-it-s-back.aspx&amp;phase=2" title="Submit Oh+My+God!+It%27s+back! to digg.com"&gt;digg it!&lt;/a&gt; | &lt;a href = "http://reddit.com/submit?url=http://honestillusion.com/blogs/blog_0/archive/2007/12/04/oh-my-god-it-s-back.aspx&amp;title=Oh+My+God!+It%27s+back!" title="Submit Oh+My+God!+It%27s+back! to reddit.com"&gt;reddit!&lt;/a&gt;&lt;/div&gt;&lt;img src="http://honestillusion.com/aggbug.aspx?PostID=4567" width="1" height="1"&gt;</description></item><item><title>My First CodePlex Project : SnitzMember</title><link>http://honestillusion.com/blogs/blog_0/archive/2007/06/20/my-first-codeplex-project-snitzmember.aspx</link><pubDate>Wed, 20 Jun 2007 18:33:33 GMT</pubDate><guid isPermaLink="false">0c240a87-1bdc-4d60-96f7-7d0531c1460e:4566</guid><dc:creator>James</dc:creator><slash:comments>0</slash:comments><description>
  &lt;p&gt;After many months to checking out the new projects on CodePlex almost daily, it's finally time for me to create one.  &lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt;As you might know, I also run the website, NJTheater.com.  Written about 10 years ago, all in classic ASP, it has a forum section -- which uses the open source Snitz Forum package.&lt;/p&gt; &lt;p&gt;Over the years, the membership has grown (over 3000 registered users), and I started to use the forum membership database, to manage authorization in other others of the website.&lt;/p&gt; &lt;p&gt;Now ASP.Net v2 came out, with it's built in Authentication/Authorization system, I thought "That's exactly what I need for my website" --- except it used a completely different db schema then the one I already had (and each hashed the passwords in different ways, so no conversion from one to the other was possible).&lt;/p&gt; &lt;p&gt;Fortunately, the membership system was built on using the Provider model, so I just had to create a Membership provider which fitted the interface, but used the existing membership database.   &lt;a href="http://www.codeplex.com/SnitzMember" target="_blank"&gt;SnitzMember&lt;/a&gt; is the provider.&lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt;Also, you may have noticed that I referred to this as my &lt;em&gt;first&lt;/em&gt; CodePlex project.  Well, you may have also noticed that I referred to NJTheater.com as 10 years old, and written in Classic ASP.  Stay Tuned.&lt;/p&gt;
&lt;div class = "shareblock"&gt;&lt;strong&gt;Share this post:&lt;/strong&gt; &lt;a title="Email My+First+CodePlex+Project+%3a+SnitzMember" href = "mailto:?body=Thought you might like this: http://honestillusion.com/blogs/blog_0/archive/2007/06/20/my-first-codeplex-project-snitzmember.aspx&amp;subject=My+First+CodePlex+Project+%3a+SnitzMember"&gt;Email it!&lt;/a&gt; | &lt;a href = "http://del.icio.us/post?url=http://honestillusion.com/blogs/blog_0/archive/2007/06/20/my-first-codeplex-project-snitzmember.aspx&amp;title=My+First+CodePlex+Project+%3a+SnitzMember" title="Submit My+First+CodePlex+Project+%3a+SnitzMember to del.icio.us" &gt;bookmark it!&lt;/a&gt; | &lt;a href = "http://www.digg.com/submit?url=http://honestillusion.com/blogs/blog_0/archive/2007/06/20/my-first-codeplex-project-snitzmember.aspx&amp;phase=2" title="Submit My+First+CodePlex+Project+%3a+SnitzMember to digg.com"&gt;digg it!&lt;/a&gt; | &lt;a href = "http://reddit.com/submit?url=http://honestillusion.com/blogs/blog_0/archive/2007/06/20/my-first-codeplex-project-snitzmember.aspx&amp;title=My+First+CodePlex+Project+%3a+SnitzMember" title="Submit My+First+CodePlex+Project+%3a+SnitzMember to reddit.com"&gt;reddit!&lt;/a&gt;&lt;/div&gt;&lt;img src="http://honestillusion.com/aggbug.aspx?PostID=4566" width="1" height="1"&gt;</description></item><item><title>What's inside a foreach() statement?</title><link>http://honestillusion.com/blogs/blog_0/archive/2007/05/18/what-s-inside-a-foreach-statement.aspx</link><pubDate>Fri, 18 May 2007 15:31:47 GMT</pubDate><guid isPermaLink="false">0c240a87-1bdc-4d60-96f7-7d0531c1460e:4562</guid><dc:creator>James</dc:creator><slash:comments>2</slash:comments><description>
  &lt;p&gt;Recently I was looking at some C# code where the author, to loop through some collection,  would frequently use call GetEnumerator() and the manually step through the collections, calling MoveNext().  It seemed to me that the code could be written more cleanly using a foreach.   I got to wondering it the author knew some funky optimization detail, that I didn't, that made his code more efficient.&lt;/p&gt; &lt;p&gt;So I tried an experiment.  I wrote two methods: one, a lightly adapter version of the code I had been studying; and the other, the equivalent code, using a foreach.  I compiled them, and examined the generated IL in Reflector.&lt;/p&gt; &lt;div class="csharpcode"&gt;&lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;void&lt;/span&gt; Test1(Dictionary&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;, &lt;span class="kwrd"&gt;int&lt;/span&gt;&amp;gt; bag)&lt;/pre&gt;&lt;pre&gt;{&lt;/pre&gt;&lt;pre class="alt"&gt;    Dictionary&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;, &lt;span class="kwrd"&gt;int&lt;/span&gt;&amp;gt;.Enumerator enumerator = bag.GetEnumerator();&lt;/pre&gt;&lt;pre&gt;    &lt;span class="kwrd"&gt;while&lt;/span&gt; (enumerator.MoveNext())&lt;/pre&gt;&lt;pre class="alt"&gt;    {&lt;/pre&gt;&lt;pre&gt;        &lt;span class="kwrd"&gt;if&lt;/span&gt; (bag.ContainsKey(enumerator.Current.Key))&lt;/pre&gt;&lt;pre class="alt"&gt;        {&lt;/pre&gt;&lt;pre&gt;            bag.Add(enumerator.Current.Key, 5);&lt;/pre&gt;&lt;pre class="alt"&gt;        }&lt;/pre&gt;&lt;pre&gt;    }&lt;/pre&gt;&lt;pre class="alt"&gt;}&lt;/pre&gt;&lt;pre&gt; &lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;void&lt;/span&gt; Test2(Dictionary&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;, &lt;span class="kwrd"&gt;int&lt;/span&gt;&amp;gt; bag)&lt;/pre&gt;&lt;pre&gt;{&lt;/pre&gt;&lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;foreach&lt;/span&gt; (KeyValuePair&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;, &lt;span class="kwrd"&gt;int&lt;/span&gt;&amp;gt; item &lt;span class="kwrd"&gt;in&lt;/span&gt; bag)&lt;/pre&gt;&lt;pre&gt;    {&lt;/pre&gt;&lt;pre class="alt"&gt;        &lt;span class="kwrd"&gt;if&lt;/span&gt;(bag.ContainsKey(item.Key))&lt;/pre&gt;&lt;pre&gt;        {&lt;/pre&gt;&lt;pre class="alt"&gt;            bag.Add(item.Key, 5);&lt;/pre&gt;&lt;pre&gt;        }&lt;/pre&gt;&lt;pre class="alt"&gt;    }&lt;/pre&gt;&lt;pre&gt;}&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;I'll spare you the IL listings, but Test1() was shorter by a small amount.  More interestingly, while some parts of the IL matched in both methods, a lot was different.  I studied the code to see the variations. One difference was in Test1, get_Current() was called twice, but only once in Test2(). But, mainly, Reflector claimed the Test2 had try and finally statements, which I figured were essentially a using{} block.  After a bit of playing, I came up with this:&lt;/p&gt;
&lt;div class="csharpcode"&gt;&lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;void&lt;/span&gt; Test3(Dictionary&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;, &lt;span class="kwrd"&gt;int&lt;/span&gt;&amp;gt; bag)&lt;/pre&gt;&lt;pre&gt;{&lt;/pre&gt;&lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;using&lt;/span&gt; (Dictionary&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;, &lt;span class="kwrd"&gt;int&lt;/span&gt;&amp;gt;.Enumerator enumerator = bag.GetEnumerator())&lt;/pre&gt;&lt;pre&gt;    {&lt;/pre&gt;&lt;pre class="alt"&gt;        &lt;span class="kwrd"&gt;while&lt;/span&gt; (enumerator.MoveNext())&lt;/pre&gt;&lt;pre&gt;        {&lt;/pre&gt;&lt;pre class="alt"&gt;            KeyValuePair&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;, &lt;span class="kwrd"&gt;int&lt;/span&gt;&amp;gt; item = enumerator.Current;&lt;/pre&gt;&lt;pre&gt;            &lt;span class="kwrd"&gt;if&lt;/span&gt; (bag.ContainsKey(item.Key))&lt;/pre&gt;&lt;pre class="alt"&gt;            {&lt;/pre&gt;&lt;pre&gt;                bag.Add(item.Key, 5);&lt;/pre&gt;&lt;pre class="alt"&gt;            }&lt;/pre&gt;&lt;pre&gt;        }&lt;/pre&gt;&lt;pre class="alt"&gt;    }&lt;/pre&gt;&lt;pre&gt;}&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Except for a few insignificant deviations (the order of temporaries on the stack, the placement of NOP instructions), Test2 &amp;amp; Test3 produce identical IL code.  More interesting, if I ask Reflector to disassemble the assembly into C# code, it displays identical foreach loops for both methods.  &lt;/p&gt;
&lt;p&gt;So, what have we learned from this?  Well, a simply manual GetEnumerator loop will end up skipping the call to Enumerator.Dispose().  Whether that is an optimization or a bug depends on your code.  And, if you're not careful, you'll probably end up retrieving the Current property more than you need to.&lt;/p&gt;
&lt;p&gt;In the end, you're probably better off calling foreach, which, one suspects, is why it was added to the language in the first place.&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;&lt;a href="http://www.dotnetkicks.com/kick/?url=http://honestillusion.com/blogs/blog_0/archive/2007/05/18/what-s-inside-a-foreach-statement.aspx"&gt;&lt;img alt="kick it on DotNetKicks.com" src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http://honestillusion.com/blogs/blog_0/archive/2007/05/18/what-s-inside-a-foreach-statement.aspx" border="0" /&gt;&lt;/a&gt;
&lt;div class = "shareblock"&gt;&lt;strong&gt;Share this post:&lt;/strong&gt; &lt;a title="Email What%27s+inside+a+foreach()+statement%3f" href = "mailto:?body=Thought you might like this: http://honestillusion.com/blogs/blog_0/archive/2007/05/18/what-s-inside-a-foreach-statement.aspx&amp;subject=What%27s+inside+a+foreach()+statement%3f"&gt;Email it!&lt;/a&gt; | &lt;a href = "http://del.icio.us/post?url=http://honestillusion.com/blogs/blog_0/archive/2007/05/18/what-s-inside-a-foreach-statement.aspx&amp;title=What%27s+inside+a+foreach()+statement%3f" title="Submit What%27s+inside+a+foreach()+statement%3f to del.icio.us" &gt;bookmark it!&lt;/a&gt; | &lt;a href = "http://www.digg.com/submit?url=http://honestillusion.com/blogs/blog_0/archive/2007/05/18/what-s-inside-a-foreach-statement.aspx&amp;phase=2" title="Submit What%27s+inside+a+foreach()+statement%3f to digg.com"&gt;digg it!&lt;/a&gt; | &lt;a href = "http://reddit.com/submit?url=http://honestillusion.com/blogs/blog_0/archive/2007/05/18/what-s-inside-a-foreach-statement.aspx&amp;title=What%27s+inside+a+foreach()+statement%3f" title="Submit What%27s+inside+a+foreach()+statement%3f to reddit.com"&gt;reddit!&lt;/a&gt;&lt;/div&gt;&lt;img src="http://honestillusion.com/aggbug.aspx?PostID=4562" width="1" height="1"&gt;</description><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/Code/default.aspx">Code</category><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/.Net/default.aspx">.Net</category><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/Programming/default.aspx">Programming</category></item><item><title>More Fun with C# Interators : A Counting Iterator</title><link>http://honestillusion.com/blogs/blog_0/archive/2007/05/08/more-fun-with-c-interators-a-counting-iterator.aspx</link><pubDate>Tue, 08 May 2007 16:30:14 GMT</pubDate><guid isPermaLink="false">0c240a87-1bdc-4d60-96f7-7d0531c1460e:4551</guid><dc:creator>James</dc:creator><slash:comments>4</slash:comments><description>
  &lt;p&gt;
    &lt;a href="http://www.dotnetjunkies.com/WebLog/mwherman2000/default.aspx"&gt;Michael Herman&lt;/a&gt; recently discovered a &lt;a href="http://msdn2.microsoft.com/en-us/library/ms131103.aspx"&gt;typo in the MSDN docs&lt;/a&gt;:   "&lt;a href="http://www.dotnetjunkies.com/WebLog/mwherman2000/archive/2007/05/06/233749.aspx"&gt;IEnumberable: the integer version of IEnumerable? :-)&lt;/a&gt; "&lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt;This reminded me of a method that I've been planning on presenting here:  A simple Counting iterator.  Basically, it appears to be a collection filled with a sequences of numbers.  For example, the following code will print the number from 20 to 41 stepping by three:&lt;/p&gt; &lt;p&gt;&lt;font face="Courier New" size="3"&gt;foreach(int i in Iter.Count(20,41, 3))&lt;br /&gt;     WL(i.ToString());&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font face="Courier New" size="3"&gt;&lt;/font&gt; &lt;/p&gt; &lt;p&gt;It's also good to create an actual collection pre-filled with sequence of numbers:&lt;/p&gt; &lt;p&gt;&lt;font face="Courier New" size="4"&gt;List&amp;lt;int&amp;gt; ll = new List&amp;lt;int&amp;gt;(Iter.Count(5));&lt;/font&gt;&lt;/p&gt; &lt;p&gt;The code follows:&lt;/p&gt; &lt;div class="csharpcode"&gt;&lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; Iter&lt;/pre&gt;&lt;pre&gt;{&lt;/pre&gt;&lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;public&lt;/span&gt; IEnumerable&amp;lt;&lt;span class="kwrd"&gt;int&lt;/span&gt;&amp;gt; Count(&lt;span class="kwrd"&gt;int&lt;/span&gt; start, &lt;span class="kwrd"&gt;int&lt;/span&gt; end)&lt;/pre&gt;&lt;pre&gt;    {&lt;/pre&gt;&lt;pre class="alt"&gt;        &lt;span class="kwrd"&gt;return&lt;/span&gt; Count(start, end, 1);&lt;/pre&gt;&lt;pre&gt;    }&lt;/pre&gt;&lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;public&lt;/span&gt; IEnumerable&amp;lt;&lt;span class="kwrd"&gt;int&lt;/span&gt;&amp;gt; Count(&lt;span class="kwrd"&gt;int&lt;/span&gt; end)&lt;/pre&gt;&lt;pre&gt;    {&lt;/pre&gt;&lt;pre class="alt"&gt;        &lt;span class="kwrd"&gt;return&lt;/span&gt; Count(1, end, 1);&lt;/pre&gt;&lt;pre&gt;    }&lt;/pre&gt;&lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;public&lt;/span&gt; IEnumerable&amp;lt;&lt;span class="kwrd"&gt;int&lt;/span&gt;&amp;gt; Count(&lt;span class="kwrd"&gt;int&lt;/span&gt; start, &lt;span class="kwrd"&gt;int&lt;/span&gt; end, &lt;span class="kwrd"&gt;int&lt;/span&gt; step)&lt;/pre&gt;&lt;pre&gt;    {&lt;/pre&gt;&lt;pre class="alt"&gt;        &lt;span class="kwrd"&gt;for&lt;/span&gt;(&lt;span class="kwrd"&gt;int&lt;/span&gt; i = start; i &amp;lt;=end; i+=step)&lt;/pre&gt;&lt;pre&gt;            &lt;span class="kwrd"&gt;yield&lt;/span&gt; &lt;span class="kwrd"&gt;return&lt;/span&gt; i;&lt;/pre&gt;&lt;pre class="alt"&gt;    }&lt;/pre&gt;&lt;pre&gt;}&lt;/pre&gt;&lt;/div&gt;Also, I should point out that the idea behind this came from a C++ iterator that I first saw presented by Andy Koenig. &lt;a href="http://www.dotnetkicks.com/kick/?url=http://honestillusion.com/blogs/blog_0/archive/2007/05/08/more-fun-with-c-interators-a-counting-iterator.aspx"&gt;&lt;img alt="kick it on DotNetKicks.com" src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http://honestillusion.com/blogs/blog_0/archive/2007/05/08/more-fun-with-c-interators-a-counting-iterator.aspx" border="0" /&gt;&lt;/a&gt;
&lt;div class = "shareblock"&gt;&lt;strong&gt;Share this post:&lt;/strong&gt; &lt;a title="Email More+Fun+with+C%23+Interators+%3a+A+Counting+Iterator" href = "mailto:?body=Thought you might like this: http://honestillusion.com/blogs/blog_0/archive/2007/05/08/more-fun-with-c-interators-a-counting-iterator.aspx&amp;subject=More+Fun+with+C%23+Interators+%3a+A+Counting+Iterator"&gt;Email it!&lt;/a&gt; | &lt;a href = "http://del.icio.us/post?url=http://honestillusion.com/blogs/blog_0/archive/2007/05/08/more-fun-with-c-interators-a-counting-iterator.aspx&amp;title=More+Fun+with+C%23+Interators+%3a+A+Counting+Iterator" title="Submit More+Fun+with+C%23+Interators+%3a+A+Counting+Iterator to del.icio.us" &gt;bookmark it!&lt;/a&gt; | &lt;a href = "http://www.digg.com/submit?url=http://honestillusion.com/blogs/blog_0/archive/2007/05/08/more-fun-with-c-interators-a-counting-iterator.aspx&amp;phase=2" title="Submit More+Fun+with+C%23+Interators+%3a+A+Counting+Iterator to digg.com"&gt;digg it!&lt;/a&gt; | &lt;a href = "http://reddit.com/submit?url=http://honestillusion.com/blogs/blog_0/archive/2007/05/08/more-fun-with-c-interators-a-counting-iterator.aspx&amp;title=More+Fun+with+C%23+Interators+%3a+A+Counting+Iterator" title="Submit More+Fun+with+C%23+Interators+%3a+A+Counting+Iterator to reddit.com"&gt;reddit!&lt;/a&gt;&lt;/div&gt;&lt;img src="http://honestillusion.com/aggbug.aspx?PostID=4551" width="1" height="1"&gt;</description></item><item><title>I'm Back!</title><link>http://honestillusion.com/blogs/blog_0/archive/2007/04/30/i-m-back.aspx</link><pubDate>Mon, 30 Apr 2007 04:22:21 GMT</pubDate><guid isPermaLink="false">0c240a87-1bdc-4d60-96f7-7d0531c1460e:4512</guid><dc:creator>James</dc:creator><slash:comments>0</slash:comments><description>
  &lt;p&gt;I've come within a few hours of letting the entire month of April go by without post even one blog entry.  So, where the heck have I been?&lt;/p&gt; &lt;p&gt;First off, on the 9th, I started a new job.  I'm now back to working in NYC, and back to working on C#, after a seven month deversion into C++ in New Jersey.&lt;/p&gt; &lt;p&gt;I'm now working with WCF, so hopefully, after I figure out exactly what I doing, I'll have some fun thoughts to share with my vast reading audience.&lt;/p&gt;
&lt;div class = "shareblock"&gt;&lt;strong&gt;Share this post:&lt;/strong&gt; &lt;a title="Email I%27m+Back!" href = "mailto:?body=Thought you might like this: http://honestillusion.com/blogs/blog_0/archive/2007/04/30/i-m-back.aspx&amp;subject=I%27m+Back!"&gt;Email it!&lt;/a&gt; | &lt;a href = "http://del.icio.us/post?url=http://honestillusion.com/blogs/blog_0/archive/2007/04/30/i-m-back.aspx&amp;title=I%27m+Back!" title="Submit I%27m+Back! to del.icio.us" &gt;bookmark it!&lt;/a&gt; | &lt;a href = "http://www.digg.com/submit?url=http://honestillusion.com/blogs/blog_0/archive/2007/04/30/i-m-back.aspx&amp;phase=2" title="Submit I%27m+Back! to digg.com"&gt;digg it!&lt;/a&gt; | &lt;a href = "http://reddit.com/submit?url=http://honestillusion.com/blogs/blog_0/archive/2007/04/30/i-m-back.aspx&amp;title=I%27m+Back!" title="Submit I%27m+Back! to reddit.com"&gt;reddit!&lt;/a&gt;&lt;/div&gt;&lt;img src="http://honestillusion.com/aggbug.aspx?PostID=4512" width="1" height="1"&gt;</description></item><item><title>Design Patterns: Thoughts on the Singleton Pattern</title><link>http://honestillusion.com/blogs/blog_0/archive/2007/03/13/design-patterns-thoughts-on-the-singleton-pattern.aspx</link><pubDate>Tue, 13 Mar 2007 20:27:52 GMT</pubDate><guid isPermaLink="false">0c240a87-1bdc-4d60-96f7-7d0531c1460e:4478</guid><dc:creator>James</dc:creator><slash:comments>2</slash:comments><description>
  &lt;p&gt;(Note: I started writing this a couple days ago --- a short while before Andrew Matthews published his own very similar &lt;a href="http://aabs.wordpress.com/2007/03/08/singleton-%e2%80%93-the-most-overused-pattern/"&gt;article&lt;/a&gt;.  He, of course, finished his first...)&lt;/p&gt; &lt;p&gt;(Update: Fixed the spelling/grammar, and then wrote a bit more)&lt;/p&gt; &lt;p&gt;Lately on some of the blogs I read, I've been seeing  people giving code implementing various Design Patterns.  Much of it, I thought, wasn't particularly good, so I figured I'd inflected the blogosphere with my takes on some of them.&lt;/p&gt; &lt;p&gt;I'll start with everyone's favorite Pattern : The Singleton.&lt;/p&gt; &lt;p&gt;However, before I get to code, I figure I should give some principles for proper use:&lt;/p&gt; &lt;p&gt;&lt;strong&gt;1. You will, almost certainly, never actually need a singleton.&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Singletons are, by far, the most overused, misused, and generally abused Design Pattern.  &lt;/p&gt; &lt;p&gt;&lt;strong&gt;2. The Singleton pattern is used to model objects of which there &lt;em&gt;can be&lt;/em&gt; only one (in the universe).  It is not intended for objects for which you &lt;em&gt;happen to need&lt;/em&gt; only one in your program.&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;For example, some might want to create a singleton for "currently logged-in user", based on the idea that can only be one "currently logged-in user".  But no.  There are many users, one just happens to be logged in now.  That is not a place not a singleton.&lt;/p&gt; &lt;p&gt;If you have just one of an object, and you want to make sure that when you reference that object anywhere in your program, you refer specifically to that one object, you do &lt;em&gt;not&lt;/em&gt; need a singleton.  What you want is a completely different programming technique known as a G&lt;em&gt;lobal Variable.&lt;/em&gt;  &lt;/p&gt; &lt;p&gt;"Wait a minute", you say.  "Aren't global variables &lt;em&gt;evil&lt;/em&gt;?"&lt;/p&gt; &lt;p&gt;Well, not exactly evil, but they are definitely frowned upon, and they will definitely cause problems if they are not handled properly.  However, the important point here is that regardless of how you refer to your global variable -- whether it's as "&lt;font face="Courier New"&gt;g_MyVar"&lt;/font&gt;  or "&lt;font face="Courier New"&gt;pMasterPtr-&amp;gt;pMyStructPtr-&amp;gt;MyVar&lt;/font&gt;" or "&lt;font face="Courier New"&gt;CMySingleton.Instance().MyVar&lt;/font&gt;" -- It's &lt;em&gt;still &lt;/em&gt;a global variable and will still have all the problems associated with one.  If you are going to have to deal with all those problems anyway, you might as well choose the method which is both the most easily understood, most efficient, and requires the least typing.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Side Note:&lt;/strong&gt; The second example of "renamed global variables" above came from an actual C program I was involved with some years ago.  pMasterPtr pointed to a (malloc'ed) struct, which was just a collection of pointers to other malloc'ed structs (one of each).  The elements of these structs had nothing to do with each, beyond the fact that they were all associated with a particular module.  The project leader proudly announced that the program had "only one global variable".  On program start-up, the "Structure Allocated Assignment Block" (i.e., SAAB, named after my car, over my objections) was malloc'ed, and then assigned to pMasterPtr (which I think was actually called pSAAB), then the other struct were malloc'ed and their pointers stored in the SAAB.  We could have just as easily made the elements of the secondary structs, elements of the primary struct, or just plain hard allocated data items, and it would have have no effect on the program --- the only difference is that this plan allowed the boss to say it had "only one global variable" --- which is, of course, nonsense -- it had dozens, they just had awkward names.  Additionally, due to a over-eager company coding policy, every access to a pointer had to be proceeded by a check if it were NULL, so, we'd have long blocks of code like this:&lt;/p&gt; &lt;blockquote&gt;&lt;pre class="code"&gt;&lt;span&gt;if&lt;/span&gt; (pSAAB == NULL)
{
    PrintErrorMessage();
    &lt;span&gt;return&lt;/span&gt;;
}
&lt;span&gt;if&lt;/span&gt; (pSAAB-&amp;gt;pIOStruct == NULL)
{
    PrintErrorMessage();
    &lt;span&gt;return&lt;/span&gt;;
}
pSAAB-&amp;gt;pIOStruct-&amp;gt;nColor = NewColor;&lt;/pre&gt;&lt;/blockquote&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;
&lt;p&gt;When actually a simple line like this would have sufficed:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;g_nIOColor = NewColor;&lt;/font&gt;&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;The point of all the was to show to what great length some programmers would go to, to pretend that they don't use global variables.   And this leads directly to our obsession with, and abuse of, singletons.&lt;/p&gt;
&lt;p&gt;Now, when you find something in your application of which there &lt;em&gt;Can Be Only One&lt;/em&gt;, such as the Screen or the Mouse or the Keyboard, then you have a place for a singleton.  And in these cases, in .Net, I suggest using a static class.&lt;/p&gt;
&lt;p&gt;"Wait a minute", you say.  "Aren't static classes as singletons &lt;em&gt;evil&lt;/em&gt;?"&lt;/p&gt;
&lt;p&gt;Well, not exactly evil, but they are definitely frowned upon, mainly because they aren't inherently thread-safe.  However, no singleton technique is inherently thread-safe.  The methods of making a singleton and serializing access are completely separate.  The basic logic here is that if you are going to go to the trouble of allocating a singleton, it's easy to remember to also add the code to serialize access, but if you're going to take the easy way out on the singleton, you'll probably forget about synchronization also.  Not a particularly rational design strategy, but we haven't talked about a rational design policy yet in this article.&lt;/p&gt;
&lt;p&gt;So, we've created the static class, and carefully implement thread-safe access, now do we have a good case for a singleton.  Still, no.  Because, as I pointed out earlier, a singleton is just a special kind of global variable.  Which means it has all the problems of a global variable. For instance, going back to another earlier example, the currently logged on user.  This appears to be a perfect candidate for a global variable if not actually a singleton.  And it was in that light the High-Priced Consultant Who Was Designing The System (on another project I worked on years ago -  C++ this time), decided that there would be "just a handful" of global variables in the app, one of which was "CurrentUser".  And I immediately protested -- I was assigned to write the administration module, where an admin user could log-in and &lt;em&gt;impersonate &lt;/em&gt;another user.  Hence many (most) of the tasks in the app was to perform had to be done for &lt;em&gt;this specified user,&lt;/em&gt;  who is not necessarily the (singular) CurrentUser.  Nevertheless, everyone else on the team used the global CurrentUser throughout the app, and I was forced to re-write much of it, to pass EffectiveUser as a parameter.&lt;/p&gt;
&lt;p&gt;"Wait a minute", you say.  "Aren't you talking about a global variable, not a singleton?"  Yes, but the same rules apply.  Consider the examples I gave before of true singletons: the Screen, or the Mouse or the Keyboard.  Can you say for sure that you application will only ever have to deal with one of each of them?  Multiple monitors are already quite fashionable, and in this connected world, having a local user &amp;amp; a remote user, sharing one screen but each with their own mouse &amp;amp; keyboard isn't that unusual.&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;&lt;a href="http://www.dotnetkicks.com/kick/?url=http://honestillusion.com/blogs/blog_0/archive/2007/03/13/design-patterns-thoughts-on-the-singleton-pattern.aspx"&gt;&lt;img alt="kick it on DotNetKicks.com" src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http://honestillusion.com/blogs/blog_0/archive/2007/03/13/design-patterns-thoughts-on-the-singleton-pattern.aspx" border="0" /&gt;&lt;/a&gt;
&lt;div class = "shareblock"&gt;&lt;strong&gt;Share this post:&lt;/strong&gt; &lt;a title="Email Design+Patterns%3a+Thoughts+on+the+Singleton+Pattern" href = "mailto:?body=Thought you might like this: http://honestillusion.com/blogs/blog_0/archive/2007/03/13/design-patterns-thoughts-on-the-singleton-pattern.aspx&amp;subject=Design+Patterns%3a+Thoughts+on+the+Singleton+Pattern"&gt;Email it!&lt;/a&gt; | &lt;a href = "http://del.icio.us/post?url=http://honestillusion.com/blogs/blog_0/archive/2007/03/13