Определение 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 для сложения).