I need to get the delegate reference of a method with open generic type arguments as a delegate. Is this possible?
It's straightforward to convert a non-generic method to a delegate, but when it comes to open generics, the CLR doesn't seem to recognize that the method signature of a delegate type with open generics is compatible with MethodInfo
of a method with the same generic type arguments.
In this code, TestNonGeneric
fails, but TestGeneric
passes.
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using System.Threading.Tasks;
namespace DelegatesWithOpenGenerics
{
[TestClass]
public partial class Tests
{
public delegate object SaveDelegateNonGeneric(object item);
public delegate T SaveDelegateGeneric<T>(T item) where T : class;
[TestMethod]
public async Task TestNonGeneric()
{
var methodInfo = GetType().GetMethod(nameof(SaveMethodNonGeneric));
var @delegate = Delegate.CreateDelegate(typeof(SaveDelegateNonGeneric), this, methodInfo);
}
[TestMethod]
public async Task TestGeneric()
{
var methodInfo = GetType().GetMethod(nameof(SaveMethodGeneric));
var @delegate = Delegate.CreateDelegate(typeof(SaveDelegateGeneric<>), this, methodInfo);
}
public object SaveMethodNonGeneric(object item)
{
return default;
}
public T SaveMethodGeneric<T>(T item) where T : class
{
return default;
}
}
}
Obviously, the method info is missing a generic type argument in the generic version. Perhaps the CLR simply does not allow the creation of a delegate without all the type arguments specified.If that's the case, I'd just like to know. It would be particularly good to see some documentation about this but I couldn't find anything in the official documentation.
The error that I get is:
Cannot bind to the target method because its signature is not compatible with that of the delegate type.'
Also note that this compiles:
var @delegate = (SaveDelegateNonGeneric)SaveMethodNonGeneric;
But this doesn't:
var @delegate = (SaveDelegateGeneric<>)SaveMethodGeneric;
The compilation error is:
Unexpected use of an unbound generic name
Aucun commentaire:
Enregistrer un commentaire