如何创建一个循环遍历列表并将要访问的数据成员作为输入参数的函数

How can I make a function that loops over a list and takes which data member to access as input parameter

我有一个数据类型 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;
}

你可以给一个函数作为带有签名的参数 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 是一个 lambda-expression,它定义了某种函数(在本例中)将 PlayerStats 实例和 returns [=15= 作为输入].

在代码中,您可以将 type 视为 "function"/"method" 并使用 type(y) 调用它(使用 y a 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);