Once upon a Delegate   1 comment

For the short life as a computer programmer I’ve enjoyed so far, the most miss, or not at all, understood feature of programming are delegates and, subsequently, handlers and events. I’ll try, here, to provide easily understandable way of looking at this mystery for so many ‘good’ programmers.

 

What is a delegate?

According to MSDN, a delegate is a type-safe and secure function pointer. To me this mean, a delegate is a definition of a method signature, i.e., it defines input and output parameter types for methods. Having this in mind, the following delegate definition:

delegate int StringToIntDelegate(string input);


…means that the methods compliant with this delegate, receive a string as input parameters and return an integer.

 

What is it worth?

By the first paragraph of this post, one might notice that the great majority of programmer don’t use (or so they think, as will see further down) delegates which means that they’re not essential for a computer programme to work. But, in the same direction, neither are classes and that’s not a place one wants to go. Delegates, like classes, provide strongly typed encapsulation and polymorphism whose purpose and consequences are the elimination of code redundancy and thus then probability of error and simplifies error correction.

 

An example

For instance, imagine we are implementing a class for form input field to wrap is properties and provide some validation. It would be nice to be able to generically but strongly-typed access a method that provides some validation. Bla, bla, bla…a little code might help.

The validator method would be, for our definition, a method that receives a string (that might be inserted by the user) and returns a boolean indicating if the value is valid. Something like so:

delegate bool ValidateStringDelegate(string input);

 

Having this definition at hand the implementation for an input field wrapper could look like this:

public class InputField
{
    public string Value { get; set; }
    public string Caption { get; set; }
    public ValidateStringDelegate Validator { get; set; }
    public bool IsValid { get { return Validator(Value); } }
}

 

A validator method could look like so:

bool MinimumLengthValidator(string value)
{ return value.Length > 3; }

 

An instance of InputField could look like so:

var field = new InputField(); 
field.Caption = "Property Caption";
field.Validator = new ValidateStringDelegate(MinimumLengthValidator);

 

And, at any time, there’s a safe and strongly typed way of checking if the field is valid, like:

if (field.IsValid)
    Console.WriteLine("Incorrect input!");
else
    Console.WriteLine("Input OK!");

 

 

Lambdas and delegates

I’d say lambdas and delegates are one of coding best friends ever. This happens because, as long as the delegate (the method signature, remember?) is defined a lambda expression is all that is needed to implement a method. Taking the example above, there are other shorter ways of instantiating an InputField. The following are valid and with the exact same outcome:

field.Validator = MinimumLengthValidator;

ValidateStringDelegate validator = (value) => { return value.Length > 3; };
field.Validator = validator;

field.Validator = (value) => { return value.Length > 3; };

…and, the one I would write…

field.Validator = value => value.Length > 3;

 

All these are possible because the signature of the method is established. By the time this line of code is reached, everybody knows that Validator property is to be a method that receives a string and returns a boolean.

Note that this:

var validator = (value) => { return value.Length > 3; };

is not valid and will result in compiler error because the compiler can’t tell what type value is supposed to be.

 

What about handlers and events?

As there is no chicken or egg, the event comes first.

Conceptually, and as the naming suggests, an event something that is suppose to be used (raised, so they say) when something happens. Technically it is just a delegate defined property like in the example above but whose setting is limited by the compiler. This means you can add methods to it but you can’t set it but, in my next post, I’ll explain delegate operations and the reason for this will be clear.

If will look at the customary implementation of an event in a class (or interface) it looks like so:

event HandlerType EventName;

 

Here, HandlerType is a defined delegate. In fact, our first delegate definition is just as valid as any other to use in the definition of an event:

event ValidateStringDelegate ValidateEvent;

 

This means that any handler assigned to this event must match the signature of ValidateStringDelegate.

Yes, although it is not the usual .Net approach, an event handler can have a return value. I’ll expose more on events in a future post but I’ll drop a simple implementation of the InputField class above that would be more useful in some scenarios, for instance, when the validation processing is to be called from some external object holding the InputField instance.

public class InputField
{
    public string Value { get; set; }
    public string Caption { get; set; }
    public bool IsValid { get; private set; }
    public event ValidateStringDelegate Validation;
    public void Validate()
    {
        if (null == Validation)
            IsValid = true;
        else
            IsValid = Validation(Value);
    }
}

With this implementation, a form holding the InputField would just need to call Validate method and everything else would run its course in a safe and strongly-typed manner. Here, the naming ‘event’ makes less sense conceptually but I’ll get there in a future post.

 

Conclusion

Hope this made sense and that it may help at least one programmer doing better code.

Advertisements

Posted 2011/02/08 by Bigsby in General

Tagged with , , , ,

One response to “Once upon a Delegate

Subscribe to comments with RSS.

  1. Pingback: Gambolling with Delegates « Bigsby Spot

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: