简体   繁体   中英

C# Reflection return method content as Delegate

I am working on an ability system that has pre written functions in the Abilities class and handles also Runtime methods, so I use delegates for lambda expression as well. Obviously I need to call the pre written methods using Reflection.

I use a delegate that wraps a method:

public delegate void AbilityAction();

The Abilities class contains all the Ability-Methods.

I want to make the following section static:

var mi = Abilities.instance.GetType ().GetMethod (abilities[i].name, BindingFlags.Instance | BindingFlags.NonPublic) as MethodInfo; 

AbilityAction code = (AbilityAction)Delegate.CreateDelegate(typeof(AbilityAction), this, mi);

And then call it:

AbilityAction code = GetMethodInClass(abilities[i].name /*e.g. MegaJump*/, Abilities, AbilityAction);

I have tried my best but it gives me errors:

this

A constraint cannot be special class `System.Delegate'

public static Delegate GetMethodInClass<T, D>(string methodName, T sourceClass, D delegateType) where D : Delegate {
    var mi = sourceClass.GetType().GetMethod (methodName, BindingFlags.Instance | BindingFlags.NonPublic) as MethodInfo;    
    return (D)Delegate.CreateDelegate(typeof(delegateType), this, mi);
}

Thanks in advance.

I can't see what you're actually trying to do without the delegate type and example method, but ... reading between the lines as best as I can, here's a similar example that works:

using System;
using System.Reflection;

class Foo
{

    public int Bar(string whatever) => whatever.Length;
}

delegate int AbilityAction(string name);
static class Program
{


    static void Main(string[] args)
    {
        var foo = new Foo();
        var action = GetMethodInClass<AbilityAction>(nameof(foo.Bar), foo);

        int x = action("abc");
        Console.WriteLine(x); // 3
    }

    public static D GetMethodInClass<D>(string methodName, object target) where D : Delegate
    {
        var mi = target.GetType().GetMethod(methodName,
            BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
        return (D)Delegate.CreateDelegate(typeof(D), target, mi);
    }
}

Note: if you don't have C# 7.3, the method needs some minor tweaks:

    public static D GetMethodInClass<D>(string methodName, object target) where D : class
    {
        var mi = target.GetType().GetMethod(methodName,
            BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
        return (D)(object)Delegate.CreateDelegate(typeof(D), target, mi);
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM