Tuesday, May 26, 2009

C# Puzzle No.16 (advanced)

Anonymous delegates are used extensively in C#. Can you imagine Linq without anonymous delegates?

No matter if an anonymous delegate is defined using "delegate" keyword or as a lambda expression, the delegate does not have any "name" you could use to reference it elsewhere. And frankly, there's no point for an anonymous delegate to have a name ... or maybe there is?

Your goal is to be able to define recursive anonymous delegate in a single expression, so for example you can use such recursive anonymous delegate in Linq.

Specifically, following code should compile and produce a result according to the specification:

   1: List<int> list = new List<int>() { 1,2,3,4,5 };
   2:  
   3: foreach ( var item in
   4:     list.Select( i => [....] ) )
   5:  
   6:    Console.WriteLine( item );
   7:  
   8: /* in the above line, the [....] should be replaced with a body of
   9:    an anonymous recursive delegate defined as follows:
  10: 
  11:    f(i) = 1 when i <= 1
  12:    f(i) = f(i-1) when i>1
  13: 
  14:    ( f(i) is always 1 when i >= 1 )
  15: 
  16:    You can add any auxiliary code under one condition:
  17:    the definition of the recursive delegate can only occur in place of [....]
  18: */
And yes, this is possible in C#.

Friday, May 22, 2009

No source code available for current location

Such message hit us today. Unfortunately, none of standard solutions works.

Stepping through in VS gives "No source code [...]", running from OS shell ends the application with "This Program Has Performed an Illegal Operation [...]".

The code raising the message is nothing special:

   1: instance.Property1 = something;
   2: instance.Property2 = somethingelse;
   3: instance.Property3 = yetsomethingelse;

All properties of the class are inherited from a base class from an external assembly and this has been my first clue. I thought that for some reason the assembly containing the base class is not referenced properly, so that altough I can see all properties in IDE, an older version of the assembly is used during the debuggin session and the other version just does not contain "Property2".


Since "Property2" had just been added a build or two ago, I've been almost sure that this is the issue.


Unfortunately, the issue turned out to be completely unrelated to assembly versioning.


It turned out that the class has yet another property, "Property4" which has also been added a build or two ago, and the Property4 has been implemened incorrectly, causing the stack to overflow.


The runtime crash was then caused by the stack overflow when Property4 was executed.


Why then the Visual Studio has been raising the "No source code available [...]" when stepping through the call to Property2?


I have no darn idea. I can only imagine that Visual Studio tries to be smart and caches calls to properties just "in advance", in case you need them in a while. When stepping through Property2, Property4 has probably been executed to cache its value. And the stack overflow confused Visual Studio.


Does such issue always confuses Visual Studio then?


Yes. Just try it on following code:



   1: using System;
   2: using System.Collections.Generic;
   3: using System.Linq;
   4: using System.Text;
   5:  
   6: namespace ConsoleApplication51
   7: {
   8:     class Test
   9:     {
  10:         public int Property1 { get { return 1; } }
  11:         public int Property2 { get { return 2; } }
  12:         public int Property3 { get { return Property3; } }
  13:  
  14:     }
  15:  
  16:     class Program
  17:     {
  18:         static void Main( string[] args )
  19:         {
  20:             Test test = new Test();
  21:  
  22:             var t1 = test.Property1;
  23:             var t2 = test.Property2;
  24:             var t3 = test.Property3;
  25:  
  26:         }
  27:     }
  28: }

Correct behavior: put a breakpoint in line 22, run the code with debugging enabled, step to line 23 and move your move pointer over "test" in line 20. When you unfold the properties of the object, you'll see "Function evaluation was aborted" under "Property3".


Incorrect behavior: put a breakpoint in line 22, run the code with debuggin enabled, then step to liine 23 and to line 24 and then move your mouse over "test.Property3" in line 24. Wait a second or two and the code will eventually crash, ending the debugging session without any prompt or message.


I guess something related to the latter issue has caused the former issue for us.

Thursday, May 7, 2009

C# Puzzle No.15 (intermediate)

We have two types of "comparers" in C#: the IComparer (IComparer<T>) interface and Comparison<T>.

In deep past, before generics were introduced, the base class library used IComparer everywhere. For example, the ArrayList class can sort items using custom IComparer passed as a parameter to the Sort() method.

When generics were introduced, the base class library in many cases allows either an IComparer or Comparison to be passed to sorting methods. For example, the List<T>'s Sort method accepts either the former or the latter.

It's fairly easy to convert from IComparer to Comparison<T>. Take a look at this example:

   1: class Program
   2:  {
   3:      class IntSorter : IComparer
   4:      {
   5:          #region IComparer Members
   6:  
   7:          public int Compare( object x, object y )
   8:          {
   9:              return ( (int)x ).CompareTo( (int)y );
  10:          }
  11:  
  12:          #endregion
  13:      }
  14:  
  15:      static void Main( string[] args )
  16:      {
  17:          List<int> l = new List<int>() { 4,3,2,5,3,2,1 };
  18:         
  19:          /* 
  20:             convert the an IComparer to Comparison<int>
  21: 
  22:             (x,y) => ( new IntSorter() ).Compare( x, y ) 
  23: 
  24:             is the answer
  25:           */
  26:          l.Sort( ( x, y ) => ( new IntSorter() ).Compare( x, y ) );
  27:  
  28:          /* test */
  29:          l.ForEach( i => Console.Write( i ) );
  30:  
  31:          Console.ReadLine();
  32:      }
  33:  }

However, what should we do to convert the other way around?


Specifically, take a look at this code snippet



   1: class Program
   2:  {
   3:      /* this is the Comparison<int> to be converted */
   4:      static int IntComparer( int x, int y )
   5:      {
   6:          return x.CompareTo( y );
   7:      }
   8:  
   9:      static void Main( string[] args )
  10:      {
  11:          ArrayList a = new ArrayList() { 1, 5, 3, 3, 2, 4, 3 };
  12:  
  13:          /* the ArrayList's Sort method accepts ONLY an IComparer */
  14:          a.Sort( how to pass the IntComparer here ? );
  15:  
  16:          Console.ReadLine();
  17:      }
  18:  }
and find an ellegant way to pass the Comparison<int> as IComparer to ArrayList's Sort method.

C# Puzzle No.14 (advanced)

Suppose we have a generic interface:

   1: public interface IGenericInterface<TValue>
   2: {
   3:    ... interface contract
   4: }

Theoretically this interface can be implemented by any class:



   1: class Foo : IGenericInterface<Bar>
   2: {
   3:   ...
   4: }
   5:  
   6: class Bar : IGenericInterface<Baz>
   7: {
   8:   ...
   9: }

The question is: how do we restrict the interface usage so that the generic parameter can only match the class the interface is implemented on?


Specifically, this should be valid:



   1: class Foo : IGenericInterface<Foo>
   2: {
   3: }

and this should not compile:



   1: class Foo : IGenericInterface<Bar>
   2: {
   3: }
I belive this question has at least few different answers and I wonder which solution would be the most ellegant one.