2015-01-21 2 views
2

У меня есть тип данных PlayerStats, который содержит много разных членов данных. Я хочу рассчитать оценку, которая отличается для каждого члена данных (ниже приведен пример статистики.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; 
} 

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

Что-то вроде

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; 
} 
+0

Использование MemberExpression. – CodeCaster

ответ

4

Вы можете дать функцию в качестве параметра с подписью 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, что определяет некоторый вид f (в этом случае) принимает в качестве примера экземпляр PlayerStats и возвращает double.

В коде, вы можете увидеть type как «функции»/«метод» и называем его type(y)y в PlayerStats, например).

+1

@Oday: есть ли определенная причина, чтобы сделать функцию 'type2' также функцией? –

+0

В первой функции второй операнд - ValueTable.PointsPerGoals. Во второй функции второй операнд - ValueTable.type2. Я могу заключить, что оба операнда умножения могут быть изменены. –

+0

@Oday: no: первая функция принимает только один параметр: 'PlayerStats',' double' в сигнатуре является типом результата. «Func », вероятно, полезен только в том случае, если результат может измениться (например, генератор случайных чисел). Здесь разумно предположить, что вес останется фиксированным ... –

1

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

+1

Это будет работать, но оно более неэффективно и менее безопасно: используя лямбда-выражения, компилятор может проверить, существует ли аспект на самом деле. В то время как отражение использует строки. Если в какой-то момент вы переименуете свойство, оно сломается. Я думаю, что лучше не использовать отражение, если оно не является абсолютно полезным. –

+0

Я согласен, но отказ от безопасности типов дает вам максимальную гибкость при назначении любого существующего или будущего имущества для использования в статистике. –

1

Вы можете передать 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); 
+0

«ValueTable», вероятно, дает статистически зависимые веса? –

+1

@CommuSoft Возможно, но для меня это скорее похоже на константу (только на основе ее имени). –