How in C# do you create a true singlecast delegate. i.e a delegate instance that can reference one (and only one) method in its invocation list and so be used as a callback (for a single subscriber) rather than an event (which may have many subscribers).
The Framework has the classes System.Delegate and System.MulticastDelegate, which gives the mistaken impression that System.Delegate is singlecast and System.Multicast delegate adds multicast capability. But the MSDN documentation for System.Delegate http://msdn.microsoft.com/en-us/library/system.delegate.aspx indicates that System.Delegate is in fact multicast…
“The invocation list of a delegate is an ordered set of delegates in which each element of the list invokes exactly one of the methods represented by the delegate.”
…while the documentation for System.MulticastDelegate does not really explain what extra behaviour it provides.
The official documentation in this area is pretty confusing, but one thing which is clear is that end-users cannot derive from either System.Delegate or System.MulticastDelegate. So is there any way supported by the framework to create a true singlecast delegate that can be used as a variable to store a reference to a single callback?
@dtb. If I can use a singlecast delegate then the need for the runtime check is eliminated. Of course it’s true that the application logic could still fail in other ways, such as the wrong handler being assigned, but at least if I use a singlecast delegate then the problem of there being multiple handlers where I only expect one is one problem that simply cannot exist, hence there is one less thing to check, simpler unit tests, more elegant design. Also if a delegate for a method with a return value has multiple handlers in its invocation list, then it is the value returned by the last handler in the list that is returned to the caller, not the first.
If you really need a “singlecast” delegate with an event why don’t you simply implement your own add/remove methods for that event?
The “problem” of
Delegateis thatMulticastDelegateis a derived class so if anyone assigns aMulticastDelegateobject to aDelegatevariable then you’ll always have aMulticastDelegate.For example we can simplify the default
eventimplementation to this:Now let’s change the event implementation to:
Now what you have is (almost) a singlecast delegate, because of event syntax users can’t assign directly a multicast delegate and only the last assigned delegate is stored. If your users are really malicious they can create a
MulticastDelegateand then add that delegate to your event handler. If you really need to prevent this you may add this check to theaddmethod: