我只想像这样的一种通用方法来创建各种类型的委托。
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,而ret
是null
。
在C#中可以吗?
dynamic
,generic
或linq.exprssion
的名字。应该使用Reflection
完成此操作。以上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不能缩短它。