Main

3rd lecture -- globalization and windows forms

Slides

Source codes

Notes, corrections etc.

  • Contravariance of delegates -- In the lecture, I have tried to show you that delegates in C# are contravariant (see MSDN article). First, let me show you a correct example of contravariance, similar to the one from the MSDN article:
    class MainClass
    {
    delegate int MyDel(System.Collections.ArrayList l);
    public static int ReturnSomething(Object e)
    {
    return 1;
    }
    public static void Main(string[] args)
    {
    System.Collections.ArrayList a = new System.Collections.ArrayList() {4,5,6};
    MyDel m = new MyDel(ReturnSomething);
    Console.WriteLine(m(a));
    }
    }
    You may see that the delegate m is assigned a method ReturnSomething, although the parameter types do not match exactly (ArrayList is derived from Object). There is an intuitive explanation of why the above example should work: the method assigned to m should be able to take ArrayList and return an integer. However, even the method ReturnSomething can do this, and it is not important that the method can take more general parameters as inputs.
    Now, here is the (incorrect) example from the lecture:
    class MainClass
    {
    delegate int MyDel(int i);
    public static int ReturnZero(Object e)
    {
    return 1;
    }
    public static void Main(string[] args)
    {
    MyDel m = new MyDel(ReturnZero);
    Console.WriteLine(m(0));
    }
    }
    We get an error in compile time. To see why it does not work, read this discussion (note that they talk about covariance, but the explanation is valid even for contravariance). Just a brief summary of the discussion: from very strict point of view, value types such as int are not derived from object, only boxed versions of value types are. Boxing and unboxing is done implicitly in many cases (e.g. when passing an integer to a method that accepts Object), but not in this case.