咨询区
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
我想到了两个转换方法。
提取目标的 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);}使用 Invoke 赋值
static void Main(string[] args){SomeDelegate a = Inc;Func<int, int> b = Inc;Func<int, int> c = a.Invoke;}点评区
这种需求也挺有意思的,不过 a.Invoke 和 a(x) 这两个方式非常不错,学习了。