c# - 如何在 C# 中包装具有未知数量和类型的参数的 Func<T1...Tn> ?

标签 c# delegates func

假设我有这门课:

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)Pow(a, b) ,但我不知道如何将现有函数(具有任意数量的参数)绑定(bind)到 Func 。显然它的声明并不总是 Func<float>但是Func<float, float> , Func<float, float, float>

我寻找过Func , delegate , Action但仍然不知道如何拥有这个可以保存和执行具有不同数量参数的函数的“函数胶囊”。为简单起见,我认为唯一的输入和输出类型是 float .

我正在考虑使用类似 Func<List<float>> 的东西但我想知道是否有更好的选择。

最佳答案

我想提出一个更准确地适合OP描述的场景的答案。关键在于 Delegate.DynamicInvoke 的使用,它允许您将无限数量的参数传递给委托(delegate)。

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 泛型类型来静态强制执行此操作。

关于c# - 如何在 C# 中包装具有未知数量和类型的参数的 Func<T1...Tn> ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58753416/

相关文章:

c# - 如何将返回 `Either` 的方法绑定(bind)到 Language-Ext 中接受 `Option` 的方法?

c# - CEFsharp 浏览器等待网站完全加载

ios - '(NSObject) -> () -> ViewController( )' does not conform to expected type ' classDelegate'

c# - 如何从 Expression<Func<T, bool>> 谓词中获取属性、运算符和值?

c# - 我们可以在 Windows Phone 8 的应用程序中以编程方式获取已安装应用程序的列表吗?

iphone - 在 iOS Game Kit 中,是接收数据 :fromPeer:inSession:context part of a delegate protocol?

ios - 在容器 View 中设置委托(delegate)

Python + sqlalchemy : how to process timedelta on database side?

.net - 您可以从 MethodInfo 对象获取 Func<T> (或类似的)吗?

c# - LINQ to Entities 中的 Enum.HasFlag?