2

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
  • 1
    This isn't very clear. What sort of "something else" could there be? How would it be different? .NET delegates' design is largely tied into events, where you have a chain of functions to call when some event occurs. – Telastyn Sep 9 '14 at 20:20
  • For example it wouldn't have methods such as Invoke. – Isaac Kleinman Sep 9 '14 at 20:21
  • What is it you want to know exactly about delegates, the way they're working, or how to work with them? It's unclear to me what you're asking. – Will Marcouiller Sep 9 '14 at 20:21
  • Could you give an example of the code that you find confusing? – FrustratedWithFormsDesigner Sep 9 '14 at 20:24
  • I understand how to use it. It was just confusing to me that a delegate is described as an object which accepts methods it can invoke and as an object which wraps a method. – Isaac Kleinman Sep 9 '14 at 20:24
4

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.

| improve this answer | |
0

You are right it is a bit confusing.

In the initial .net design, a Delegate was supposed to be a 'method reference' to a single target method, and a MulticastDelegate was supposed to be a container which could contain a variable number of delegates, and invoke them as a batch.

However, before the release of .net 1.0 it was decided to merge the functionality of Delegate and MulticastDelegate, so that every delegate is actually an instance of MulticastDelegate, regardless whether it has one or multiple targets. Apparently it was not possible to clean up the API after this change, so we now have a somewhat confusing API.

For example, a delegate has the Target property which has a reference to the method to invoke. But in case of a delegate with multiple targets, this property just returns a random one of the targets.

The method GetInvocationList() is confusing for the same reason. It is supposed to return an array of all the targets in a delegate. Since there is not a separate type for single-target delegates, it has to return an array of MulticastDelegates, one MulticastDelegate for each target. In the case of a single-target delegate it just returns an array with one element which is the original delegate itself.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.