How to detect compatibility between delegate types?

I have a test like this:

receivingType.IsAssignableFrom(exportingType))

Which works most of the time, but does not return the desired result when the types involved are delegate types. For example, if exportingType is Action<object, EventArgs> and receivingType is EventHandler, I want the result to be true but the above expression is false. The result I am looking for is true since the two delegates have equivalent method signatures and in fact in C# are actually assignable to each other (although I understand that's probably C# syntax magic).

So my question is, what would the equivalent test look like for delegates that would provide the desired compatibility result?

Jon Skeet
people
quotationmark

If you choose to ignore parameter/return type covariance/contravariance (both the variance supported by the compiler since C# 2.0 and the generic covariant/contravariance with in / out), demanding just equality of types, you could use:

public static bool AreCompatible(Type delegate1, Type delegate2)
{
    MethodInfo method1 = delegate1.GetMethod("Invoke");
    MethodInfo method2 = delegate1.GetMethod("Invoke");

    return method1.ReturnType == method2.ReturnType &&
           method1.GetParameters().Select(p => p.ParameterType)
                  .SequenceEqual(method2.GetParameters()
                                         .Select(p => p.ParameterType));
}

(As noted in comments, you might also want to check for out/ref parameters...)

people

See more on this question at Stackoverflow