throw new ArgumentException(SR.Argument_NeedNonGenericType, nameof(t));
}
- // COMPAT: This block of code isn't entirely correct.
- // Users passing in typeof(MulticastDelegate) as 't' skip this check
- // since Delegate is a base type of MulticastDelegate.
- Type? c = t.BaseType;
- if (c != typeof(Delegate) && c != typeof(MulticastDelegate))
+ // For backward compatibility, we allow lookup up of existing delegate to
+ // function pointer mappings using abstract MulticastDelegate type. We will check
+ // for the non-abstract delegate type later if no existing mapping is found.
+ if (t.BaseType != typeof(MulticastDelegate) && t != typeof(MulticastDelegate))
{
throw new ArgumentException(SR.Arg_MustBeDelegate, nameof(t));
}
VerifyDelegate(functionDelegate, targetMethod);
}
+ [Fact]
+ [ActiveIssue("https://github.com/dotnet/runtime/issues/48379", TestRuntimes.Mono)]
+ public void GetDelegateForFunctionPointer_MulticastDelegate_ThrowsMustBeDelegate()
+ {
+ IntPtr ptr = Marshal.AllocHGlobal(16);
+ AssertExtensions.Throws<ArgumentException>("t", () => Marshal.GetDelegateForFunctionPointer(ptr, typeof(MulticastDelegate)));
+ AssertExtensions.Throws<ArgumentException>("t", () => Marshal.GetDelegateForFunctionPointer<MulticastDelegate>(ptr));
+ Marshal.FreeHGlobal(ptr);
+ }
+
private static void VerifyDelegate(Delegate d, MethodInfo expectedMethod)
{
Assert.IsType<NonGenericDelegate>(d);