Как я могу сделать функцию, которая зацикливается на списке и принимает какой элемент данных для доступа в качестве входного параметра

У меня есть тип 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);

Вы можете поместить имена свойств в качестве строковых параметров и искать свойства по имени, используя отражение.

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