调用Func<比;与参数
本文关键字:参数 Func 调用 | 更新日期: 2023-09-27 18:10:16
我正在使用MEF
导入方法。我调用这个方法来获取所有导出的方法:
var methods = container.GetExports<Func<int,int,double>,MyMetadata>("contract name");
注:有时Func<int,int,double>
会改变。例如,它可能有更多的参数:Func<int,int,int,double>
。
当我触发方法时,我知道要传递多少参数。我的问题是如何动态地将参数传递给导入的方法?
更新: IEnumerable<Lazy<Func<int,int,double>,MyMetadata>> Plugins;
public IEnumerable RunAllPlugins(int a, int b)
{
//my old approach
foreach (var p in Plugins)
{
dynamic a = p;
var b = a.Value.Invoke(a,b); //here I want to pass parameters dynamically
}
//this is new approach which is answer
//now I can pass parameters like array of objects
foreach(var lazyMethod in Plugins)
{
Delegate d=lazyMethod.Value;
object[] numbers=new object[]{1,2};
var result=d.DynamicInvoke(numbers);
}
return null;
}
一旦你得到了Func<>
,得到它的类型:
Type type=someFunction.GetType();
现在获取Invoke
成员:
var methodInfo=type.GetMember("Invoke");
这是你执行委托时实际调用的方法。你可以在methodInfo上调用GetParameters
来查看它需要多少个参数。
如果您已经知道要添加多少参数,以及它们的类型,那么事情就容易多了。你只需要分配给一个委托并调用DynamicInvoke
:
Delegate d=someFuncInstance;
object[] numbers=new object[]{1,2};
var result=d.DynamicInvoke(numbers);
result
将是需要强制转换的object
实例。someFuncInstance
是你从某处得到的Func<>
的一个实例。
对于你的MEF例子,它应该是这样的:
var methods=container.GetExports<Func<int,int,double>,MyMetadata>("contract name");
foreach(var lazyMethod in methods)
{
Delegate d=lazyMethod.Value;
object[] numbers=new object[]{1,2};
var result=d.DynamicInvoke(numbers);
}
methods
的类型应该是IEnumerable<Lazy<Func<int,int,double>>
,所以一个简单的
foreach(var method in methods)
{
method.Value(a,b);
}
应该工作。或者,如果您想保存它以供以后使用:
Func<int,int,double> mySavedDelegate = methods.First();
//...
mySavedDelegate(a,b);
编辑:导出接口并从导入的接口执行所需的方法,而不是直接导出方法,这是一个更好的实践。我从来没有做过后者,但从你的问题中假设这是可能的。
可变函数应该在这里工作。
double Magic(params int[] args)
{
switch(args.Count)
{
case 2: return args[0]+args[1];
case 3: return args[0]+args[1]/args[3];
default: throw new Exception("Not supported");
}
}
,然后调用魔法(1、2);或魔法(1、2、3);
我猜你超载了Func<>
接口…
正如我所理解的,你想要得到的是一个具有特定签名的方法列表:它必须是返回double
并接收2 integers
的方法?所以也许你应该返回(!)一个List<>
作为返回(!)值?
第二:不可能在特定的Func<>
或Action<>
或其他地方适合所有方法。当然,有些函数会列出不同的输入参数和不同的返回值。对吧?因此,如果(!)您只想处理返回double
并接收2个integers
的函数,那么对于这些类型的方法,List<>
将只返回(!)。请阅读更多关于函数签名
第三:我猜这是一个错误的使用MEF。基本上MEF所说的是:在你的应用程序中定义接口,使用它,好像它是用new
创建的,我(MEF)将在运行时插入它。实际上你不需要来获取任何方法的列表。只要确保两边都支持/define/继承这些方法,并像在你的应用中定义的那样使用它们