Stupid C# trick

Not really a ‘trick’ per se, but while I was trying to explain the LINQ mechanics to someone, I came up with this example.  It’s the kind of thing that someone could argue is a compiler bug (which it isn’t), but only if they don’t understand how LINQ’s implemented (and specifically, how you can plug in your own code for the various extension methods called in the post-translation code).

Even if it were a compiler bug, it’s not one I would argue is worth fixing given the simplicity of the workaround (initialize the int to something).  Once you do, you get the expected output of 123 and 234 on separate lines.

The below code will fail to compile with error CS0165: Use of unassigned local variable ‘outputInt’

 

Code Snippet
  1. using System;
  2. using System.Linq;
  3.  
  4. class Program
  5. {
  6.     static void Main(string[] args)
  7.     {
  8.         args = new[] { "foo", "123", "bar", "", null, "234", "baz" };
  9.  
  10.         int outputInt;
  11.         var results = from arg in args
  12.                       where int.TryParse(arg, out outputInt)
  13.                       select outputInt;
  14.  
  15.         foreach (var result in results)
  16.         {
  17.             Console.WriteLine(result);
  18.         }
  19.     }
  20. }

Advertisements

3 thoughts on “Stupid C# trick

  1. “Once you do, you get the expected output of 123 and 234 on separate lines.” Sure. You get it *by accident*. Even with the initialization the code is not correct as it stands; you are modifying part of a closure. Suppose you make a minor change to the query:

    from arg in args where int.TryParse(arg, out outputInt) orderby outputInt select outputInt;

    And hey, now the query is producing garbage as a result. Every part of the query shares the same outputInt variable, and that variable changes its value in strange ways as the query progresses.

    The right way to do this is to make a helper method MyTryParse that returns an int? rather than modifying a variable.

    • First and foremost, thanks so much for the reply! I’m humbled by your continued willingness to help others, and I look forward to seeing more about Roslyn!

      Second, you’re obviously absolutely right. Thanks so much for the detailed explanation, and especially for the modified query being a perfect example of the problem with the original code. 🙂

Comments are closed.