当前位置: 代码迷 >> 综合 >> 如何将自定义的 Delegate 转成 Func 委托?
  详细解决方案

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

热度:91   发布时间:2024-01-12 07:38:46.0

咨询区

  • 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) 这两个方式非常不错,学习了。

  相关解决方案