您可以传递动态命名的委托Func <>参数吗? method(“ FuncdelegateNameOfMethod”)

时间:2019-04-26 07:51:10

标签: c# .net delegates

您可以将方法传递给采用Func <>的另一个方法。但是,您可以将其作为动态命名的字符串来传递,这样就可以即时传递什么方法吗?

1 个答案:

答案 0 :(得分:2)

  

您可以将一个方法传递给另一个采用Func<>的方法。

将“传递值”与“首先创建值”分开是值得的。当您编写代码时,例如:

InvokeSomeDelegate(MethodToInvoke);

正在执行方法组转换以创建委托实例。换句话说,它等同于:

Func<Whatever> func = MethodToInvoke;
InvokeSomeDelegate(func);

所以真正的问题不在于如何将字符串传递到方法中,而是如何基于字符串创建委托。反过来又引出了一种方法,所用类型等问题。

您要使用的框架方法是Delegate.CreateDelegate,但是确切的使用方法将取决于上下文,以便可以通过反射找到正确的MethodInfo。这是一个示例:

using System;
using System.Reflection;

class Test
{
    static void Main()
    {
        InvokeFunc("Double");
        InvokeFunc("Quadruple");
        InvokeFunc("AddOne");
    }

    static void InvokeFunc(string name)
    {
        // Note that in our case they're all private static methods. You'd
        // need to adjust the binding flags if that's not the case. If you
        // need to worry about multiple overloads, that makes it harder too.
        MethodInfo method = typeof(Test)
            .GetMethod(name, BindingFlags.NonPublic | BindingFlags.Static);
        // TODO: Validate that you've got a method
        var func = (Func<int, int>) Delegate.CreateDelegate(
            typeof(Func<int, int>), // Delegate type to create                                                            
            null, // Target of method call; null because ours are static
            method); // Method to create a delegate for
        var result = func(10);
        Console.WriteLine($"{name}(10) => {result}");
    }

    static int Double(int x) => x * 2;
    static int Quadruple(int x) => x * 4;
    static int AddOne(int x) => x + 1;
}

请注意,所有反射查找方法然后创建委托都相对较慢。如果这样做对性能有重大限制,则可能需要添加缓存。