Как я могу сделать функцию, которая зацикливается на списке и принимает какой элемент данных для доступа в качестве входного параметра
У меня есть тип PlayerStats, который содержит много разных членов данных. Я хочу рассчитать оценку, которая отличается для каждого элемента данных (в приведенном ниже примере рассматривается statistics.nrOfGoals).
private double getScore()
{
double strength = 0;
foreach (PlayerStats statistics in this.statistics)
{
double dateDiff = Math.Abs(nowDate.Subtract(statistics.date).Days / (365.25 / 12));
dateDiff = Math.Pow(dateDiff, Form1.historyFactor);
strength += (statistics.nrOfGoals * ValueTable.PointsPerGoals ) / dateDiff;
}
return strength;
}
Как я могу сделать эту функцию общей и принять, на какой элемент данных смотреть вместо создания множества похожих функций?
Что-то вроде
private double getScore(Type type, Type type2)
{
double strength = 0;
foreach (PlayerStats statistics in this.statistics)
{
double dateDiff = Math.Abs(nowDate.Subtract(statistics.date).Days / (365.25 / 12));
dateDiff = Math.Pow(dateDiff, Form1.historyFactor);
strength += (statistics.type * ValueTable.type2) / dateDiff;
}
return strength;
}
3 ответа
Вы можете дать функцию в качестве параметра с подписью PlayerStats -> Double
:
private double getScore(Func<PlayerStats,double> type, double type2)
{
double strength = 0;
foreach (PlayerStats statistics in this.statistics)
{
double dateDiff = Math.Abs(nowDate.Subtract(statistics.date).Days / (365.25 / 12));
dateDiff = Math.Pow(dateDiff, Form1.historyFactor);
strength += (type(statistics) * type2) / dateDiff;
}
return strength;
}
А затем позвоните с помощью:
getScore(x => x.nrOfGoals,ValueTable.PointsPerGoals);
x => x.nrOfGoals
является лямбда-выражением, которое определяет некоторую функцию, которая (в данном случае) принимает в качестве входных данных PlayerStats
экземпляр и возвращает double
,
В коде вы можете увидеть type
как "функция" / "метод" и вызвать его с type(y)
(с y
PlayerStats
пример).
Вы можете пройти Func<PlayerStats, double>
к вашей функции, например:
private double getScore(Func<PlayerStats, double> evaluator)
{
double strength = 0;
foreach (PlayerStats statistics in this.statistics)
{
double dateDiff = Math.Abs(nowDate.Subtract(statistics.date).Days / (365.25 / 12));
dateDiff = Math.Pow(dateDiff, Form1.historyFactor);
strength += evaluator(statistics) / dateDiff;
}
return strength;
}
И затем назовите это как (в вашем показанном случае)
getScore(x => x.nrOfGoals * ValueTable.PointsPerGoals);
Вы можете поместить имена свойств в качестве строковых параметров и искать свойства по имени, используя отражение.