Tag Archive for C#

Little semantic pitfall of try..finally

This time I would like to point out the behaviour, that should be absolutely clear to any C# developer. When an exception is thrown inside try..finally block (without catch), and consequently in the scope of a using statement, it is bubbled up to the containing scope, rather than handled in any way. It implies that try..finally without catch has in fact nothing to do with exception handling.

I have already come across learning materials that suggest the otherwise. Let’s have a look at [1] (my own translation from Polish):

With a using clause we end up having code which is proof against exceptions

and [2]:

A finally block can be used to handle any exception

In my opinion the fact, that in the very case of try..finally apart from catch an exception is simply thrown out of the scope, is not stressed enough in the literature and claims like these above can be misleading.

Going a little bit further, I consider this as a little semantic pitfall in the language. When we think of a try statement, we immediately recall exception handling mechanism. However this time this is not the case. Maybe other languages have better (i.e. more meaningful) way of expressing the intent of a code being executed at the end of a scope. Have a look at scope(exit) and scope(failure) instructions in D language in [3].

[1]. Polish magazine “Programista”, issue 6/2013 (13) p. 26

[2]. “Programming in C#, A primer, second edition”, chapter 18.8

[3]. Three Unlikely Successful Features of D

Less known feature of C# 5.0 — modified closure behaviour

If you were asked to mention new features of C# 5.0, then you would probably say, first of all, async / await. However, on MSDN there is list of changes that could hardly be considered as well-known, even after almost 1 year after .NET 4.5 RTM was published. In this post I briefly explain one of them, that in my opinion is worth remembering.

As a C# developer, you are hopefully aware of the outer variable trap issue. Yet, in the version 5.0 of the language, the behaviour of a closure has been slightly altered. Let’s take a look at first (regarding comment “switches”) half of the following code:

 
class Program
{
  static void Main(string[] args)
  {
    //* 
    List<Action> lambdas = new List<Action>();
    foreach (var i in new int[] { 0, 1 })
    {
      lambdas.Add(() => { Console.WriteLine(i); });
    }

    lambdas[0]();
    lambdas[1]();

    /*/

    List<Action> lambdas = new List<Action>();
    for (int i = 0; i <= 1; i++)
    {
      lambdas.Add(() => { Console.WriteLine(i); });
    }

    lambdas[0]();
    lambdas[1]();    

  //*/
  }
}

Now let’s try to compile it using version 3.5 and 4.5 of the compiler. This assumes default installations, the file is named Program.cs and, of course, as 4.5 version of run-time is in-place update, it resides in the directory named after 4.0.

  1. c:\Windows\Microsoft.NET\Framework\v3.5\csc.exe Program.cs && Program
  2. c:\Windows\Microsoft.NET\Framework\v4.0.30319\csc.exe Program.cs && Program

The former example results in 1 1 printed into the console and the latter results in 0 1 printed. The 1 1 result is caused by typical outer variable trap, where the lambdas are kind of bound to the captured variable itself (which in the end has a value of 1), but not to its value at the time of creation of the lambda. The breaking change introduced in version 5.0 of the language brings the behaviour to what actually might have been expected — capture the value indicated by the sequence of the code being executed. However, this works only inside foreach loop.

By switching the comments (deleting the first slash) you can prove standard for loop behaves exactly the same in both versions of compiler and results in printing 2 2 indicating outer variable trap.

Interface type parameter covariance and contravariance in C#

  • I would like this blog post to serve as a quick reference that recalls the basic concept of covariant and contravariant type parameters of generic interfaces in the C# language.
  • I tried to keep the example as simple as possible. Included comments explain the key points. No long stories and no dissertations.
  • The code does nothing, but compiles on C# 4.0 or newer compiler.
  • Try deleting the first slash character in the first line to kind of switch between the snippets (BTW this is cool trick 🙂 ).
//*
  // T is covariant
  // Implicit conversion from interface instance I<B> which has a method with RETURN type B
  // that is MORE derived than specified in target interface I<A>
  public interface I<out T> { T foo(); }
  public class IImp<T> : I<T> { public T foo() { return default(T); } }
  public class A { }
  public class B : A { }

  class Program
  {
    static void Main(string[] args)
    {
      I<A> ia = new IImp<B>();
    }
  }
/*/
   // T is contravariant
   // Implicit conversion from interface instance I<A> which has a method with ARGUMENT type A
   // that is LESS derived than specified in target interface I<B>
   public interface I<in T> { void foo(T t); }
   public class IImp<T> : I<T> { public void foo(T t) { } }
   public class A { }
   public class B : A { }

   class Program
   {
     static void Main(string[] args)
     {
       I<B> ia = new IImp<A>();
     }
   }
//*/