Tuesday, May 26, 2009

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 [....]

Friday, May 22, 2009

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 externalassembly 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:publicint Property1 { get { return 1; } }

11:publicint Property2 { get { return 2; } }

12:publicint Property3 { get { return Property3; } }

13:

14: }

15:

16:class Program

17: {

18:staticvoid 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

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:publicint Compare( object x, object y )

8: {

9:return ( (int)x ).CompareTo( (int)y );

10: }

11:

12:#endregion

13: }

14:

15:staticvoid 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:staticint IntComparer( int x, int y )

5: {

6:return x.CompareTo( y );

7: }

8:

9:staticvoid 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.

About

I am a software architect and an academic lecturer. I've been awarded Microsoft MVP in C# Architecture between 2005 and 2010. Got a PhD in computer science in 2008.
Currently I work mostly with C# and Javascript and love both languages. I consider myself a design/architecture patterns evangelist.
In 2003 I wrote first Polish book on C#/Windows programming, "Windows oczami programisty" (Windows through the eyes of a programmer) (the book is out of print)