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
🤷