Code to declare a delegate type, named SendMessageDelegate, which takes a Message as a parameter and returns void:
Code to define a method that takes an instantiated delegate as its argument:
The implemented method that runs when the delegate is called:
Code to call the SendMessage method, passing an instantiated delegate as an argument:
A delegate variable calls the associated method and is called as follows:
Delegate variables are first-class objects of the form new DelegateType(obj.Method) and can be assigned to any matching method, or to the value null. They store a method and its receiver without any parameters:4
The object funnyObj can be this and omitted. If the method is static, it should not be the object (also called an instance in other languages), but the class itself. It should not be abstract, but could be new, override or virtual.
To call a method with a delegate successfully, the method signature has to match the DelegateType with the same number of parameters of the same kind (ref, out, value) with the same type (including return type).
A delegate variable can hold multiple values at the same time:
If the multicast delegate is a function or has no out parameter, the parameter of the last call is returned.5
Although internal implementations may vary, delegate instances can be thought of as a tuple of an object and a method pointer and a reference (possibly null) to another delegate. Hence a reference to one delegate is possibly a reference to multiple delegates. When the first delegate has finished, if its chain reference is not null, the next will be invoked, and so on until the list is complete. This pattern allows an event to have overhead scaling easily from that of a single reference up to dispatch to a list of delegates, and is widely used in the CLI.
Performance of delegates used to be much slower than a virtual or interface method call (6 to 8 times slower in Microsoft's 2003 benchmarks),6 but, since the .NET 2.0 CLR in 2005, it is about the same as interface calls.7 This means there is a small added overhead compared to direct method invocations.
There are very stringent rules on the construction of delegate classes. These rules permit optimizing compilers a great deal of leeway when optimizing delegates while ensuring type safety.
Microsoft Developer Network (MSDN) Article, How to: Combine Delegates (Multicast Delegates)(C# Programming Guide), Accessed 5/20/2008 http://msdn.microsoft.com/en-us/library/ms173175(VS.80).aspx ↩
"About Microsoft's "Delegates"". Sun Developer Network. Sun Microsystems. Archived from the original on 10 February 1999. https://web.archive.org/web/19990210053040/http://www.java.sun.com/docs/white/delegates.html ↩
Wikibooks:C Sharp Programming/Delegates and Events https://en.wikibooks.org/wiki/C_Sharp_Programming/Delegates_and_Events ↩
Mössenböck, Hanspeter (2002-03-25). "Advanced C#: Variable Number of Parameters" (PDF). Institut für Systemsoftware, Johannes Kepler Universität Linz, Fachbereich Informatik. pp. 23–24. Retrieved 2011-08-04. http://ssw.jku.at/Teaching/Lectures/CSharp/Tutorial/Part2.pdf ↩
Mössenböck, Hanspeter (2002-03-25). "Advanced C#: Variable Number of Parameters". Institut für Systemsoftware, Johannes Kepler Universität Linz, Fachbereich Informatik. p. 25. Retrieved 2011-08-04. http://ssw.jku.at/Teaching/Lectures/CSharp/Tutorial/ ↩
Gray, Jan (June 2003). "Writing Faster Managed Code: Know What Things Cost". Microsoft. Retrieved 2007-09-09. http://msdn2.microsoft.com/en-us/library/ms973852 ↩
Sturm, Oliver (2005-09-01). "Delegate calls vastly sped up in .NET 2". Retrieved 2007-09-09. http://www.sturmnet.org/blog/2005/09/01/delegate-interface-speed ↩