This is the recommended pattern. There is a little flexibility, but there are a number of strict rules, if you violate any of these rules, the class will fail to load (or compile with ikvmc) with a java.lang.VerifyError.

Delegate rules:

Class must extend cli.System.MulticastDelegate.

Class must be final.

Class must have a single method named Invoke that is public, native, non-final and non-static.

Class must have a single public constructor taking an inner interface named Method and have an empty method body (actually it must call the base class default constructor using the canonical bytecode sequence).

Class may have BeginInvoke/EndInvoke methods, but if it has either one it must have both. The BeginInvoke and EndInvoke methods must have a singature that is implied by the signature of Invoke.

Class must have a public inner interface named Method with a single method named Invoke with a signature identical to the Invoke method in the class.

Class may not have any fields.

Class may not have any other native methods.

Class must be static if it is an inner class. (This isn't a real rule, it follows from the other rules.)

The delegate is usable from Java like other .NET delegates, but obviously it doesn't add much value there. The real value comes from being able to better interact with other .NET languages. For example, one cool trick is this:

I've currently defined delegates for java.lang.Runnable and java.security.PrivilegedAction as inner classes of ikvm.runtime.Delegates. There are some other candidate interfaces in IKVM.OpenJDK.Core.dll, but I'll only add them if there is demand, so let me know.

I apologize for the lameness of this, but the comment spam was driving me nuts.
In order to be able to post a comment, you need to answer a simple question. Hopefully this question
is easy enough not to annoy serious commenters, but hard enough to keep the spammers away.

Anti-Spam Question: What method on java.lang.System returns an object's original hashcode (i.e. the
one that would be returned by java.lang.Object.hashCode() if it wasn't overridden)? (case is significant)