使用一种通用方法进行CreateDelegate

时间:2019-04-12 09:49:48

标签: c# .net reflection

我只想像这样的一种通用方法来创建各种类型的委托。

public static object Boo(params object[] args) {
    return null;
}
MethodInfo boo = /* MethodInfo of Boo */

// Boo's arg.Length should be `0`
Action action = (Action)Delegate.CreateDelegate(typeof(Action), null, boo);

Func<int> action2 = (Func<int>)Delegate.CreateDelegate(typeof(Func<int>), null, boo);
Func<string, string> action3 = (Func<string, string>)Delegate.CreateDelegate(typeof(Func<string, string>), null, boo);

因此,如果您像这样调用action3

var ret = action3.Invoke("booo");

Boo的args.Length应该是1,而retnull

在C#中可以吗?

  • 没有dynamicgenericlinq.exprssion的名字。

更新

应该使用Reflection完成此操作。以上3位代表仅是示例。委托类型将在运行时确定。

3 个答案:

答案 0 :(得分:2)

你能做到吗?

Action action = () => Boo();
Func<int> action2 = () => (int)Boo();
Func<string, string> action3 = x => (string)Boo(x);

如果没有,为什么不呢?

答案 1 :(得分:2)

您可以先为常规方法定义一个委托:

public delegate object BooDelegate(params object[] args);

您可以通过以下方式使用扩展方法:

public static class DelegatesProviderExtensions
{
    public static Func<int> GetFuncOfInt(this BooDelegate booDelegate) => () => (int) booDelegate();

    public static Action GetAction(this BooDelegate booDelegate) => () => booDelegate();

    public static Func<string, string> GetFuncOfStringString(this BooDelegate booDelegate) =>
        s => booDelegate(s) as string;
}

并测试:

private static void Main(string[] args)
{
    BooDelegate boo1 = objects => 1;
    BooDelegate boo2 = objects =>
    {
        Console.WriteLine("Boo!");
        return null;
    };
    BooDelegate boo3 = objects => $"{objects[0]} World";

    Console.WriteLine(boo1.GetFuncOfInt()());
    boo2.GetAction()();
    Console.WriteLine(boo3.GetFuncOfStringString()("Hello"));
    Console.ReadLine();
}

这种方法的优点是您可以使扩展方法更完整并验证错误,并提供反馈等

答案 2 :(得分:0)

最后用这种方式完成 https://github.com/pjc0247/SlowSharp/blob/master/Slowsharp/Runner/Runner.Lambda.cs

我认为没有Linq.Expression不能缩短它。