myelin: How to write callbacks in C# and .NET

Here's a quick explanation of how delegates work in C#.  The reason this page is here is to provide some quick notes for people trying to figure out how callbacks work in various different languages.

Delegates do the same thing as interface-based callbacks in C++ (COM uses these), although are much simpler to use.

Note that Microsoft put delegates into its Java implementation (J++) but Sun doesn't like them [java.sun.com] so don't expect to see them in the official version of Java any time soon.  I've hacked together a preprocessor to let you use them in C++, so don't feel left out if you're not programming in C# or on the .NET platform (i.e. in Managed C++ or Visual Basic.NET).

If you're used to function pointers in C, a delegate is basically a pair of pointers rolled into one:

That means a single delegate passes all the information needed to locate a function in your program, whether it's a static method or associated with an object.

You define them like this in C#:

public delegate void FooCallbackType( int a, int b, int c );

When you want to use them, you make delegate out of the function you want to call:

class CMyClass
{
	public void FunctionToCall( int a, int b, int c )
	{
		// This is the callback
	}

	public void Foo()
	{
		FooCallbackType myDelegate = new FooCallbackType(
			this.FunctionToCall );
		// Now you can pass that to the function
		// that needs to call you back.
	}
}

If you want to make a delegate to point to a static method, it just looks the same:

class CMyClassWithStaticCallback
{
	public static void StaticFunctionToCall( int a, int b, int c )
	{
		// This is the callback
	}

	public static void Foo()
	{
		FooCallbackType myDelegate = new FooCallbackType(
			CMyClass.StaticFunctionToCall );
	}
}

All in all, they do the same thing as interface-based callbacks in C++, but cause a bit less trouble because you don't need to worry about naming your functions or making helper objects, and you can make delegates out of any method. They're more flexible.

They have other features which I won't cover here - for example you can make a single delegate that will call a list of functions, one by one.  Take a look at this MSDN article for more detail.