C# Delegates – Understanding Structure and Usage

cdelegates

I've been trying to understand C# delegates using Pro C# 5.

In short, the author describes the motivation for delegates as a structured way of dealing with function pointers and callbacks or two-way communication between objects.

The part I find confusing is the syntax/implementation for this:

  • On the one hand, an object of delegate type is seen as the handler
    or the one responsible for invoking some method or list of methods. To this end, it has
    methods such as Invoke() etc.

  • On the other hand, the delegate type is used as a 'wrapper' with
    which to pass around methods.

For example, it seems strange to me that a call to a delegate's GetInvocationList() returns an array of delegates. Shouldn't there be something else with which to wrap methods?

I expected there would be some other construct/type, say, MethodContainer which wraps methods. Then the syntax for adding methods to a delegate would be

class MyClass{ void Method(string s){} }

MyClass c = new MyClass();
MethodContainer container = new MethodContainer(c.Method);

delegate void MyDelegate(string s);
MyDelegate d = new MyDelegate();

d.Add(container);

d.GetInvocationList(); // returns array of MethodContainer

Best Answer

There actually is this sort of distinction made under the covers. Delegate is the single function wrapper, and MulticastDelegate is the type that is the composite form of Delegate. The confusing part is that Delegate isn't really exposed from the innards of the runtime. All delegates created by C# are multicast delegates, even if they only contain a single item.

This is because historically, delegates were largely there to make windows events work nicely, which often would have multiple listeners. Now that delegates are used more for functional programming approaches, it's a little more awkward in theory. In practice, very few people use the multicast functionality outside of events given its downsides (exceptions at any point of the chain will break it, and the caller won't know where, hard to debug) and because it's not exactly common knowledge.

Related Topic