c# - 如何包装 FuncC# 中参数的数量和类型未知?
问题描述
假设我有这个类:
public class Function {
public int argc; //number of arguments of the function
public float[] argv;
public Func<float> f; //attribute to store a function (e.g. Sin(x) or Pow(a, b))
}
我想创建包含Function
不同函数的实例,例如Sin(x)
or Pow(a, b)
,但我不知道如何将现有函数(带有任意数量的参数)绑定到Func
. 显然,它的声明并不总是Func<float>
but Func<float, float>
,Func<float, float, float>
等。
我一直在寻找Func
, delegate
,Action
但仍然没有弄清楚如何拥有这个“函数胶囊”,它可以保存和执行具有不同数量参数的函数。为简单起见,我认为唯一的输入和输出类型是float
.
我正在考虑使用类似的东西,Func<List<float>>
但我想知道是否有更好的选择。
解决方案
我想提出一个更准确地符合 OP 描述的场景的答案。关键在于使用Delegate.DynamicInvoke
它可以让您将无限数量的参数传递给委托。
public class Function<TReturn> {
private readonly object[] _argv;
private readonly Delegate _func;
public Function(Delegate func, params object[] args) {
_func = func;
_argv = args;
}
public TReturn Run() {
object v = _func.DynamicInvoke(_argv);
return (TReturn)v;
}
}
它的用法使您可以动态决定要传递的参数数量:
var s = new Function<double>((Func<double, double>)(x => Math.Sin(x)), 1 );
Console.WriteLine(s.Run()); // prints 0.8414709848078965
var p = new Function<double>((Func<double, double, double>)((a, b) => Math.Pow(a, b)), 2, 3);
Console.WriteLine(p.Run()); // prints 8
var d = new Function<string>((Func<string, double, string>)((a, b) => a + b.ToString()), "hello, ", 42);
Console.WriteLine(p.Run()); // prints "hello, 42"
请注意,类型检查仅在调用时在运行时执行,Function.Run()
而不是在构造Function
对象时执行,因为它具有动态特性。如果您确定所有传递的参数将始终属于同一类型,则可以通过添加TArg
泛型类型来静态强制执行。
推荐阅读
- pg-promise - 流:如何将行作为数组(而不是 JSON 对象)
- c# - 如何配置 Teamcitys SonarQube Runner 来分析 C# 文件
- python - 如何对列表中的连续重复项求和?
- kubernetes - Rancher v3 Api 文档不可用
- jenkins - Jenkins 通过 ssh 发布显示错误“jenkins.plugins.publish_over.BapPublisherException:无法添加 SSH 密钥。”
- reactjs - 使用 Backbone 和 React(带凉亭)构建的网站使用的是开发者版本的 react。如何让它使用 prod 版本?
- javascript - 使用 jQuery 选择材质样式
- scala - spark中的条件计数
- javascript - 使用动态字符串附加 JSON 对象键
- javascript - 获得响应后如何刷新加载 iFrame 的页面