How to make your c# code more OOP with delegates pt 1

Since I became a codementor a recurrent theme has been handling delegates. I’ll try to clarify this once and for all. This ended up as a long post so I have decided to break it into 2 parts: in this, we get a feeling of what are delegates. The next one will deal with how and when to use them.

Extending the C# type system

The c# type system is often classified as reference and value types. I won’t go into what’s the difference between these 2 since there’s a lot of information about this topic out there. Typically a developer starts an application by extending this basic type system to better model a solution for the problem he is solving (in effect, he’s creating a DSL). There are several ways to do this: if you want to extend the value type system you usually use structs whereas for the reference type system classes and interfaces are the default way.

However, there’s a 3rd way to declare a new type: delegates.

Understanding delegates

Given that a delegate type syntax it’s different than the rest of the methods to declare a new type, a lot of developers never realize that they are indeed declaring a new type. I mean consider the following:

class StockItem {
    public int SKU {get; set;}
    public string Description{get; set;}
    public decimal price{get; set;}
}

struct Point{
   public int X {get; set;}
   public int Y {get; set;}
}

interface IValidate{
    bool IsValid(object value);
}

somehow they feel alike, right? now check this out:

delegate string CallWebService(string url);

It feels odd right? It looks nothing like the other type definitions we have seen so far. It doesn’t have attributes nor methods. Just what is this?!?!
Calm down, first of all, a delegate it’s an object that holds code declared somewhere else in contrast with classes which define the behavior of its instances inside themselves. With that in mind let me tell you that, what the delegate definition is saying is what kind of code it will contain: which values can accept and return. The “method name” would be the delegate name. Now that we have a type we can create instances of it!

delegate string CallWebService(string url);

class WebServiceUtils {
   public string MakeCall(string url){...}
}

public class Test{ 
            public static main (){ 
                string anUrl = "..."; 
                var caller = new CallWebService(new WebServiceUtils().MakeCall);
                caller.Invoke(anUrl) //or could be just caller(anUrl);
             }
}

So far so good. Actually, the C# team saw the potential of delegate and in C# version 2, they decided to bring some of the best things that could happen to the language: anonymous methods. Anonymous methods are an incarnation of closures, a very powerful concept. Unluckily for us, they decided to reuse the delegate keyword for this.

delegate string CallWebService(string url);

class WebServiceUtils {
   public string MakeCall(string url){ ... }
}

public class Test{ 
 public static main (){ 
 string anUrl = "..."; 
     var caller = delegate(string url) { return new WebServiceUtils.MakeCall(url); };
     caller.Invoke(anUrl) //it could be just caller(anUrl);
 }
}

I can only imagine that the C# team was thinking that since anonymous methods were only going to be used with a delegate, it made sense to use the delegate keyword to declare not only a delegate type but a delegate instance as well. Unfortunately, this leads to further confusion since now when someone talks about a delegate, he could either be talking about a delegate type or an anonymous method.

Even worse! From MSDN:

There is one case in which an anonymous method provides functionality not found in lambda expressions. Anonymous methods enable you to omit the parameter list. This means that an anonymous method can be converted to delegates with a variety of signatures. This is not possible with lambda expressions.

Basically, it means that you can write code like:

delegate string CallWebService(string url);

class WebServiceUtils {
   public string MakeCall(string url){ ... }
}

public class Test{
   public static main (){
     string anUrl = "...";
     var caller = delegate { //<-- no parameters at all!!
            //you can have access to the variables on the same 
            //scope as where the anonymous method was declared
          return new WebServiceUtils().MakeCall(anUrl);
     };
     caller.Invoke(anUrl); 
   }
}

So now you have anonymous methods that don’t conform to the delegate definition but are still regarded as valid.

As if this wasn’t enough the 3rd version of C# brought another way to declare anonymous methods: lambda expressions.

delegate string CallWebService(string url);

class WebServiceUtils {
   public string MakeCall(string url){ ... }
}

public class Test{
   public static main (){
     string anUrl = "...";
      //this is an anonymous method too
     var caller = (url) => new WebServiceUtils().MakeCall(url);//or MakeCall(anUrl)
     caller.Invoke(anUrl); 
   }
}

uff! this was a lot for a single post. Next post will see delegates in action. Stay tuned!