【问题标题】:CreateDelegate using one general methodCreateDelegate 使用一种通用方法
【发布时间】:2019-04-12 09:49:48
【问题描述】:

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

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 名代表只是示例。委托的类型将在运行时决定。

【问题讨论】:

    标签: c# .net reflection


    【解决方案1】:

    你可以先为你的通用方法定义一个委托:

    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】:

    你能做到吗:

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

    如果没有,为什么不呢?

    【讨论】:

      【解决方案3】:

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

      我认为没有 Linq.Expression 就无法缩短。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-10-30
        • 1970-01-01
        • 2014-05-08
        • 2020-08-02
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多