Определение Func с гибким измерением в C#

В C#Я хотел бы метод, который возвращает Func, но где выражение Func зависит от некоторого входного заданного измерения.

Например, предположим, что я хочу функцию F всегда возвращать произведение своих переменных, но количество переменных может варьироваться. На данный момент я сделал следующее:

    public static Func<double[],double> DefineFunction()
    {
        Func<double[], double> F = x => Prod(x);

        return F;
    }

    public static double Prod(double[] vector)
    {
        double result = 1;
        for (int i = 0; i<vector.Length; i++)
        {
            result *= vector[i];
        }
        return result;
    }

Затем я могу определить функцию, которая выводит произведение трех аргументов следующим образом:

        Func<double[], double> G = DefineFunction();
        double test = G(new double[] { 1, 2, 3 });
        Console.WriteLine(test);

Мой вопрос, если это лучший способ сделать это. Мой подход использует другой метод только для определения Fчто кажется излишним. Позвольте мне упомянуть, что это не всегда должен быть продукт, но всегда какое-то однородное выражение, которое легко обобщается по измерениям.

2 ответа

Решение

Код, уже предоставленный, работает. Но, как уже упоминалось, Aggregate делает именно то, что вы хотите.

Console.WriteLine(new double[] {1, 2, 3, 4}.Aggregate((x, y) => x + y));

Выходы "10"

Как уже было упомянуто и опубликовано в другом месте, класс Enumerable имеет ряд методов, которые позволяют применять функцию ко всей коллекции, например, Aggregate. Тем не менее, следуя вашей логике попыток использовать Func и применить свою собственную заявку, что-то вроде ниже будет, как бы вы ее структурировали:

using System;

public class Program
{
    public static void Main(string[] args)
    {
        //define your general apply function
        Func<double[], Func<double, double, double>, double, double> G = (vars, func, init) =>
        {
            double result = init;
            foreach (var t in vars)
            {
                result = func(result,t);
            }

            return result;
        };

        //here is a product example    
        double test = G(new double[] { 1, 2, 3, 4 }, (prev, x) => prev * x, 1);
        Console.WriteLine(test);

        //here is an addition example
        test = G(new double[] { 1, 2, 3, 4 }, (prev, x) => prev + x, 0);
        Console.WriteLine(test);            
    }   
}

Выше вы можете передать любой func или выражение, такое как: (prev, x) => prev * x и массив значений типа double, и значение init (выше 1 для продукта и 0 для сложения).

Другие вопросы по тегам