如何将自定义的 Delegate 转成 Func 委托?

Posted dotNET跨平台

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何将自定义的 Delegate 转成 Func 委托?相关的知识,希望对你有一定的参考价值。

咨询区

  • AndreyAkinshin

场景是这样的,我自定义了一个 SomeDelegate 委托,然后将 Inc 方法灌入到其中,同时我也将 Inc 赋值给了 Func<int,int> 委托,参考代码如下:

class Program
    
        static void Main(string[] args)
        
            SomeDelegate a = Inc;
            Func<int, int> b = Inc;
        

        public delegate int SomeDelegate(int p);

        public static int Inc(int p)
        
            return p + 1;
        
    

现在问题来了,我想把 a 赋值给 b 这个委托,我发现居然不能转换。

Func<int, int> c = (Func<int, int>)a;

会报如下的错误:

Cannot convert type 'ConsoleApp5.Program.SomeDelegate' to 'System.Func<int, int>'

请问我该如下处理?

回答区

  • dtb

首先你要知道快捷写法的背后到底是什么?比如你提到的。

SomeDelegate a = Inc;
Func<int, int> b = Inc;

背后的真实代码为:

SomeDelegate a = new SomeDelegate(Inc); 
Func<int, int> b = new Func<int, int>(Inc);

可以看到,上面两个是完全不相干的类型实例,无法用 cast 转换,这就好像你不可能将 string 转成 Dictionary 一样,不过也有变通的解决方法,比如下面这样。

Func<int, int> c = x => a(x);

上面这种写法是语法糖,全称大概是下面这样。

class MyLambda

   SomeDelegate a;
   public MyLambda(SomeDelegate a)  this.a = a; 
   public int Invoke(int x)  return this.a(x); 


Func<int, int> c = new Func<int, int>(new MyLambda(a).Invoke);
  • Diego Mijelshon

我想到了两个转换方法。

  1. 提取目标的 Target 和 Method

static void Main(string[] args)
        
            SomeDelegate a = Inc;
            Func<int, int> b = Inc;

            Func<int, int> c = (Func<int, int>)Delegate.CreateDelegate(typeof(Func<int, int>), b.Target, b.Method);
        
  1. 使用 Invoke 赋值

static void Main(string[] args)
        
            SomeDelegate a = Inc;
            Func<int, int> b = Inc;

            Func<int, int> c = a.Invoke;
        

点评区

这种需求也挺有意思的,不过 a.Invokea(x) 这两个方式非常不错,学习了。

以上是关于如何将自定义的 Delegate 转成 Func 委托?的主要内容,如果未能解决你的问题,请参考以下文章

委托delegate,Action,Func,Predicate

如何将自定义装饰器添加到 FastAPI 路由?

[C#]action,delegate,func的用法和区别

[C#]action,delegate,func的用法和区别

C# 显示错误 'Delegate 'System.Func<...>' 不接受 1 个参数

delegate Func Action Expression