dimanche 13 septembre 2020

Convert Method with Open Generics to Delegate [duplicate]

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