Skip to content

Attempts to create delegates from generic methods declared on interfaces throws NotSupportedException #100748

Open

Description

Description

If you have an interface declared as

public interface I1
{
    public void GenericFoo<T>();
}

And a delegate declared as

public delegate void InterfaceDelegate(I1 i1);

Attempting to create an instance of that delegate with this will throw a NotSupportedException

var genericMethod = typeof(I1).GetMethod(nameof(I1.GenericFoo))!;
var method = genericMethod.MakeGenericMethod(typeof(int));
//
// This is where the NotSupportedException is throne
//
method.CreateDelegate<InterfaceDelegate>(); 

However if you instead use a non-generic method (of corse MakeGenericMethod won't be needed) but it will be able to create an instance of the deligte. Additionally if you define a new a class with a generic method that has the same signature, and a delegate for that class's method you will be able to use similar code create an instance of that delegate.

Reproduction Steps

I tried this in dotnet 6.0.420 and 8.0.203

public interface I1
{
    public void GenericFoo<T>();
}

public delegate void InterfaceDelegate(I1 i1);

public class Program
{
    public static void Main()
    {
        var genericMethod = typeof(I1).GetMethod(nameof(I1.GenericFoo))!;
        var method = genericMethod.MakeGenericMethod(typeof(int));
        //
        // This is where the NotSupportedException is throne
        //
        method.CreateDelegate<InterfaceDelegate>(); 
    }
}

Expected behavior

The above program can be run without an exception.

Actual behavior

~/Repos/MinRepro > dotnet run
Unhandled exception. System.NotSupportedException: Specified method is not supported.
   at System.Delegate.BindToMethodInfo(Object target, IRuntimeMethodInfo method, RuntimeType methodType, DelegateBindingFlags flags)
   at System.Delegate.CreateDelegateInternal(RuntimeType rtType, RuntimeMethodInfo rtMethod, Object firstArgument, DelegateBindingFlags flags)
   at System.Reflection.RuntimeMethodInfo.CreateDelegateInternal(Type delegateType, Object firstArgument, DelegateBindingFlags bindingFlags)
   at System.Reflection.MethodInfo.CreateDelegate[T]()
   at Program.Main()
~/Repos/MinRepro >

Regression?

I have only tried 6.0 and 8.0 and the behavior seems to be the same in both.

Known Workarounds

One workaround I have found is to use a DynamicMethod to create a method to invoke the generic method. It seems to work for very simple cases. However implementing that for arbitrary method signatures might tricky.

Configuration

  • Which version of .NET is the code running on? 8.0
  • What OS and version, and what distro if applicable? Mac OS X 14.4
  • What is the architecture (x64, x86, ARM, ARM64)? x64
  • Do you know whether it is specific to that configuration? Not that I'm aware of
  • If you're using Blazor, which web browser(s) do you see this issue in? N/A
~/Repos/MinRepro > dotnet --info
.NET SDK:
 Version:           8.0.203
 Commit:            5e1ceea679
 Workload version:  8.0.200-manifests.4e94be9c

Runtime Environment:
 OS Name:     Mac OS X
 OS Version:  14.4
 OS Platform: Darwin
 RID:         osx-x64
 Base Path:   /usr/local/share/dotnet/sdk/8.0.203/

.NET workloads installed:
There are no installed workloads to display.

Host:
  Version:      8.0.3
  Architecture: x64
  Commit:       9f4b1f5d66

.NET SDKs installed:
  6.0.420 [/usr/local/share/dotnet/sdk]
  8.0.203 [/usr/local/share/dotnet/sdk]

.NET runtimes installed:
  Microsoft.AspNetCore.App 6.0.28 [/usr/local/share/dotnet/shared/Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 8.0.3 [/usr/local/share/dotnet/shared/Microsoft.AspNetCore.App]
  Microsoft.NETCore.App 6.0.28 [/usr/local/share/dotnet/shared/Microsoft.NETCore.App]
  Microsoft.NETCore.App 8.0.3 [/usr/local/share/dotnet/shared/Microsoft.NETCore.App]

Other architectures found:
  None

Environment variables:
  Not set

global.json file:
  Not found

Learn more:
  https://aka.ms/dotnet/info

Download .NET:
  https://aka.ms/dotnet/download

Other information

🤷

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions