Posted on July 26, 2008 21:47 by swilliams

Delegates have come a long way since they were introduced in .NET 1.0. Back then they were only a way to refer to existing methods as variables. 2.0 allowed methods to be inlined, making them "anonymous." The 3.5 Framework does not introduce any new concepts regarding delegates, but it makes writing them much, much quicker and cleaner.

Let's reuse the example from the last post. C# 2.0's syntax for anonymous methods looked like this:

private delegate void ItemAction(ListViewItem item, int index);

private void ActOnListView(ItemAction action) {
    for (int i = 0; i < this.listView1.Items.Count; i++) {
        ListViewItem item = this.listView1.Items[i];
        action(item, i);
    }
}

public void HighliteEven() {
    this.ActOnListView(delegate(ListViewItem item, int index) {
        item.BackColor = index % 2 == 0 ? Color.Red : item.BackColor;
    });
}

The HighliteEven() method can be written with C# 3.0 as:

public void HighliteEven() {
    this.ActOnListView((x, y) => x.BackColor = y % 2 == 0 ? Color.Red : x.BackColor);
}

Whoa, where did that => thing come from? That's the new shorthand for creating an anonymous method. All it does is compresses delegate(Type object){ into something smaller. The (x, y) parameters do not need Type declarations because they are inferred from the delegate's signature as a ListViewItem and a Int32 (you'll even get intellisense on them).

This is what allows you to use all of the slick extension methods added to the standard collection classes:

List<string> stuff = new List<string>();
if (stuff.All(s => s.Length > 10)) {
    Console.WriteLine("all strings have at least 10 characters.");
}
string[] myName = stuff.Where(n => n.StartsWith("Scott"));

Single object parameters do not need parentheses, and delegates with no parameters use empty ones: ().

This type of expression is often called a Lambda. Technically, you can have multiple line lambdas, the convention is to stick with a single one1. Multiple lines of code with this syntax can quickly become messy and hard to read. Stick with the old delegate() { } syntax instead if you need it.

[1. I'm not even going to show or link to the syntax, since you shouldn't use it.]

If you are familiar with Python or Ruby (and others) this style should be familiar to you.

	# a lambda in Python
	sq = lambda x: x * x
	sq(5)
	# returns 25

	# a lambda in Ruby
	sq = lambda {|x| x * x}
	sq.call(5)
	# returns 25

.NET also provides a few prefab helper delegates. Action was provided in the 2.0 framework. It's signature looks like this:

public delegate void Action(T obj);

It has a few overloads to take up to four parameters. So, our sample code up top can be rewritten as:

private void ActOnListView(Action<ListViewItem, int> action) {
	// snip
}

Removing the ItemAction definition.

For methods that need to return something, .NET 3.5 offers several versions of a delegate called Func. The most basic is Func<TResult>(), which takes no parameters and returns an instance of whatever TResult is set to. Func<T, TResult> takes a single parameter, of type T, and also returns a TResult. Like Action, Func provides overloads for up to four parameters. These can all be backported to .NET 2.0, since they don't use any 3.5-only features:

public delegate TResult Func<TResult>();
public delegate TResult Func<T, TResult>(T obj);
// and so on

The various forms of Func are used throughout the LINQ enabled extension methods of the 3.5 Framework.

The single biggest thing to be aware of is that overuse of delegates makes code difficult to read, especially for the neophyte. If you have a particularly hairy situation, say one that has three or more nested generics and a few lambdas, all on one line, consider splitting it apart in order to increase readability. The compiler won't care, but maintainers will appreciate it.

If you have never encountered them before, delegates can feel a little awkward at first, but once you get used to them, especially with C# 3.0's lambda syntax, you won't want to go back.



Digg It!DZone It!StumbleUponTechnoratiRedditDel.icio.usNewsVineFurlBlinkList

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Posted on July 24, 2008 10:13 by swilliams

Back in Part 1, we covered the history of Delegates in the .NET Framework. As stated, in 1.1, they were a little too confined to be exceptionally useful. However, in the 2.0 Framework, Delegates were given the ability to be "Anonymous" and could be created on the fly. This allows for more elegant coding, and serves as an introduction to some concepts previously relegated to Functional Programming.

First, an example. In the previous post, this was our basic demonstration of a delegate:

public delegate void SomeFunction(int num);

public void PrintHello(int num) {
    for (int i = 0; i < num; i++) {
        Console.WriteLine("Hello."); 
    }
}

public void Main() {
    SomeFunction func = new SomeFunction(this.PrintHello);
    func(10);
}

Anonymous Methods mean that we do not have to define the PrintHello method as a part of the class, it can be created inline:

public delegate void SomeFunction(int num);

public void Main() {
    SomeFunction func = delegate(int num) {
        for (int i = 0;, i < num; i++) {
            Console.WriteLine("Hello.");
        }
    };
    func(10);
}

This in and of itself is useful; it cuts down a few lines of code, but doesn't necessarily add too much value.

Enter Closures. A Closure is "a [method] that is evaluated in an environment containing one or more bound variables." (I'll use OO terminology since this is C# related). What this means is that an anonymous method can refer and use variables defined in the scope surrounding it. Thus:

public delegate void SomeFunction(int num);

public void Main() {
    string s = "This is what will print.";

    SomeFunction func = delegate(int num) {
        for (int i = 0;, i < num; i++) {
            Console.WriteLine(s); // not defined in the delegate, but still valid
        }
    };
    func(10);
}

This of course begs the question of the ages, so what? Why would I possibly want to do something like that? Well, for a simple example, let's say you have a collection of items, say, the items in a ListView, and you have a bunch of operations you want to perform on them at different times. The non-delegate way would be to have separate methods that iterate through the list and do its thing.

public void HighliteEven() {
    for (int i = 0; i < this.listView1.Items.Count; i++) {
        ListViewItem li = this.listView1.Items[i];
        if (i % 2 == 0) {
            li.BackColor = Color.Red;
        }
    }
}

public List<ListViewItem> ExtractLong() {
    List<ListViewItem> items = new List<ListViewItem>();
    foreach (ListViewItem item in this.listView1.Items) {
        if (item.Text.Length > 50) {
            items.Add(item);
            this.listView1.Items.Remove(item);
        }
    }
    return items;
}

These are only two methods, but it's not uncommon to have upwards of a dozen, depending on how robust the UI is. If you have an ExtractLong, there's a good chance you'll need an ExtractShort, and probably more ExtractX methods too. Already you can see code duplication in the loops. Anonymous methods let you refactor this code to:

private delegate void ItemAction(ListViewItem item, int index);

private void ActOnListView(ItemAction action) {
    for (int i = 0; i < this.listView1.Items.Count; i++) {
        ListViewItem item = this.listView1.Items[i];
        action(item, i);
    }
}

public void HighliteEven() {
    this.ActOnListView(delegate(ListViewItem item, int index) {
        if (index % 2 == 0) {
            item.BackColor = Color.Red;
        }
    });
}

public List<ListViewItem> ExtractLong() {
    List<ListViewItem> items = new List<ListViewItem>();
    this.ActOnListView(delegate(ListViewItem item, int index) {
        if (item.Text.Length > 50) {
            items.Add(item);
            this.listView1.Items.Remove(item);
        }
    });
    return items;
}

This is better, but we can refactor the Extract method even more. .NET 2.0 also introduces a special delegate called Predicate<T>. If you have used the Array.Find method before, you've used Predicate<T>. A predicate simply executes an expression that returns a boolean. In Array.Find()'s case, it evaluates the object at each index of the array. If the object passes the test provided, it adds it to the return set.

We can use the same idea here to create a generic Extract method which we can give any number of comparers, greatly shortening each ExtractX method.

private List<ListViewItem> Extract(Predicate<ListViewItem> comparer) {
    List<ListViewItem> items = new List<ListViewItem>();
    this.ActOnListView(delegate(ListViewItem item, int index) {
        if (comparer(item)) {
            items.Add(item);
            this.listView1.Items.Remove(item);
        }
    });
    return items;
}

public List<ListViewItem> ExtractLong() {
    return this.Extract(delegate(ListViewItem item) {
        return item.Text.Length > 50;
    });
}

Making an ExtractShort method is just another 3 liner, who's payload is return item.Text.Length < 5; So, rather than having 8 lines of code (at least) per Extract method, you can have 3, which can be a huge savings, and makes testing far easier.

These concepts, and the syntax, may look a little intimidating, but once you have used them for a little bit, you won't want to go back. In the next post, I'll cover the updates to .NET 3.5, and show similar features in a couple other languages.



Digg It!DZone It!StumbleUponTechnoratiRedditDel.icio.usNewsVineFurlBlinkList

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Posted on June 20, 2008 13:14 by swilliams

Delegates are a big part of the .NET Framework. They were included since the beginning with .NET 1.0 and have matured since then, but in my experience I don't see them used intentionally too often.

I think the reason for this is because the concept of a delegate is kind of foreign if you have a more procedural background, using mainly languages like Visual Basic or Java, and to a certain extent, C. I certainly hadn't encountered anything like that until I started using C#, and had a difficult time wrapping my head around the concept.

To understand them better, let's take a look at the history of delegates, starting with the positively ancient and crusty .NET 1.0.

At the most basic level, a delegate serves as a way to treat a method as a variable. This means that it can be passed around to different methods, or have its execution delayed until deemed fit. A common reaction to this is "Why would I ever want to do that?" Well, it lets you do some interesting things. For starters, it makes it easier to perform certain kinds of logic at runtime without having to write a great deal of code.

And since every explanation is better with a little bit of code, let's get to it. As stated, delegates have been around for a while. With .NET 1.0, a delegate could only wrap an existing method, nothing on-the-fly:

// This is the definition of the delegate. The return type (void) and 
// arguments (int num) are the signature for any methods that 
// will be wrapped by this delegate.
public delegate void SomeFunction(int num);

// A standard method
public void PrintHello(int num) {
    for (int i = 0; i < num; i++) {
        Console.WriteLine("Hello."); 
    }
}

public void Main() {
    // PrintHello's signature matches what was declared by the 
    // delegate, so it can be used as a variable if needed.
    SomeFunction func = new SomeFunction(this.PrintHello);
    func(10);
}

Again, why does this even matter? The most useful thing about delegates is that you don't need to know which method needs to be called at compile time. One of the classical Design Patterns is the Command Pattern, which let's you abstract a common piece of functionality out to a variable, and pass it around... sound familiar? Delegates are not a complete substitute for the pattern, but can perform similar functionality with far less code. And less code is always better.

Additionally, .NET's event model is based on delegates. The EventHandler is really just a delegate that returns null and takes an Object and an EventArgs. They are also used with some of the asynchronous logic in the framework, BeginInvoke being primary.

For a real-world example, I've seen them used as a neat solution for some of the shortcomings with a Windows Form ToolBar. Back in .NET 1.1, the ToolBar still had many COM underpinnings, and the ToolBarButtons that made up the Bar did not have individual OnClick events on them; you had to handle the ToolBar's ButtonClick event, and pull the Button property from the event's arguments (this was a mess that was replaced with the ToolStrip in .NET 2.0). Once you got this, then you would need to perform some sort of test to determine the appropriate action method. Rather than have a 20 line select statement, one bright co-worker just wrapped the desired method in a delegate and dropped it into the button's Tag property. In just two lines he was able to accomplish what my 20+ did. I call that a bargain.

Here is an example of using delegates to implement a State Machine. This is just the framework for a machine, the strength of it lies in its ability to declare the edges of the graph dynamically.

public delegate Node EvalOp(State s);

public abstract class State {
    // State contains all information about the current position in the graph.
}

public class Node {
    private string _name;
    public EvalOp[] ops;

    public Node(string name) {
        this._name = name;
        this.ops = new EvalOp[] { };
    }

    public string Name {
        get { return this._name; }
    }

    public Node Evaluate(State s) {
        foreach (EvalOp op in this.ops) {
            Node n = op(s);
            if (n != null) {
                return n;
            }
        }
        // If we reach this point, we are at the end.
        return null;
    }

    private static Node _end = new Node("End");

    public static Node EndNode {
        get { return _end; }
    }
}

public abstract class Graph {
    protected Node[] nodes;
    protected Node currentNode;
    protected State state;

    public Graph() {
        this.Init();
    }

    public void Start() {
        for (this.currentNode = nodes[0]; this.currentNode != Node.EndNode; this.currentNode = this.currentNode.Evaluate(this.state)) { 
            this.Step();
        }
    }

    protected abstract void Step();

    // Create nodes and state here
    protected abstract void Init();
}

The basic operation is that each node contains an array of delegates (EvalOp) to define the edges to a new node. The EvalOp takes a State object and determines if it satisfies the requirements of the edge. If it does, it returns the next node to travel to. Each EvalOp is evaluated until the first valid Node is returned. It's not the most robust State Machine ever created, but I wanted to demonstrate delegates rather than State Machines.

I wrote a simple implementation to demonstrate it. There are three nodes, including the EndNode already created by the framework. One is called Odd, and the other is Even, and they switch back and forth depending on the value of State, which is incremented each step of the way, until 100 is reached.

public class ConcreteState : State {
    private int _count;

    // Note the lack of auto-properties in 1.0. Argh.
    public int Count {
        get { return this._count; }
        set { this._count = value; }
    }
}

public class ConcreteGraph : Graph {
    protected override void Init() {
        this.state = new ConcreteState();
        Node odd = new Node("Odd");
        Node even = new Node("Even");

        EvalOp oddTest = new EvalOp(this.OddOp);
        EvalOp evenTest = new EvalOp(this.EvenOp);
        EvalOp finishTest = new EvalOp(this.CountOp);

        odd.ops = new EvalOp[] { finishTest, oddTest };
        even.ops = new EvalOp[] { finishTest, evenTest };
        this.nodes = new Node[] { odd, even };
    }

    protected override void Step() {
        ((ConcreteState)this.state).Count++;
    }

    private Node OddOp(State s) {
        if (((ConcreteState)s).Count % 2 == 1) {
            Console.WriteLine("Odd");
        }
        return this.nodes[1]; // move to the even op
    }

    private Node EvenOp(State s) {
        if (((ConcreteState)s).Count % 2 == 0) {
            Console.WriteLine("Even");
        }
        return this.nodes[0]; // move to the odd op.
    }

    private Node CountOp(State s) {
        return ((ConcreteState)s).Count == 100 ? Node.EndNode : null;
    }
}

More complicated functionality could be added by just creating a new EvalOp delegate (like say, MultipleOfFourOp) and adding it to the proper node[s].

Delegates are not all roses of course. Their biggest shortcoming in 1.1, was that they were too rigid. You needed to have a method defined elsewhere in the app, and you couldn't do some of the neat things that other languages were able to do with similar constructs (typically called lambdas). Fortunately, .NET 2.0 significantly improved delegate's abilities and 3.5 made them extra delicious. I'll write more about them later.



Digg It!DZone It!StumbleUponTechnoratiRedditDel.icio.usNewsVineFurlBlinkList

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5