2013-02-26 2 views
2

Редактировать: Это пример программы, я понимаю, что в linq есть оператор sum. Тем не менее, я пытался спросить конкретно, как передать указатель на свойство, чтобы сделать с ним что-то сложное, не обязательно этот алгоритм суммирования.Передача указателя на свойство класса

Допустим, у меня есть класс, как это:

class Point 
{ 
    double x {get; set;} 
    double y {get; set;} 
} 

и в моей основной программе у меня было 2 функции.

double function1(List<Point> PointList) 
{ 
    double sum = 0.0; 
    foreach(Point p in PointList) 
    { 
     sum += p.x; 
    }  
    return sum; 
} 

double function2(List<Point> PointList) 
{ 
    double sum = 0.0; 
    foreach(Point p in PointList) 
    { 
     sum += p.y; 
    }  
    return sum; 
} 

Эти функции полностью идентичны за исключением того, один суммированием значений X, а другой суммированием значений Y. Поскольку они настолько похожи, я хотел бы объединить их так, что я в основном перехожу в этот список точек, и что-то, чтобы определить, что я хочу сделать X или Y основе расчета.

Я знаю, что могу поставить оператор switch и сказать ему, был ли он X или Y на основе перечисления, или число, которое определено, чтобы сказать ему, чтобы сделать X или Y. Если это было нормальная функция, я полагаю, я мог бы использовать s-делегат, но это свойство, поэтому я не уверен, как это переводится.

Так как я совмещаю эти функции во что-то вроде:

double bothFunctions(List<Point> PointList, var propertyToUse) 
{ 
    double sum = 0.0; 
    foreach(Point p in PointList) 
    { 
     sum += p.propertyToUse; 
    }  
    return sum; 
} 

Где propertyToUse указывает либо X или Y.

+1

'PointList', очевидно, не может быть параметром' out'. Вы уверены, что этот код в порядке? – jdehaan

+0

В моей реальной программе это должно быть вне, но для этого примера это не так, я удалю это. – Xantham

+0

@ Xantham в этом случае указатель - это просто делегат. См. Мой ответ. –

ответ

6

Текущие решения работают отлично, но они предполагают, что ваша операция sum или что у вас будет только два возможных свойства (X и Y).

Если вы хотите получить больше свободы, вы можете сделать:

double function(List<Point> PointList, Func<Point, double> selector) 
{ 
    double sum = 0.0; 
    foreach (Point p in PointList) 
    { 
     sum += selector(p); 
    } 
    return sum; 
} 

Тогда вы называете это так:

double sumX = function(PointList, p => p.X); 
double sumY = function(PointList, p => p.Y); 

вы будете иметь возможность писать более сложные селекторы, как:

double sumXY = function(PointList, p => p.X + p.Y); 
+0

Я верю, что это именно то, что я искал. Я буду больше смотреть в это ключевое слово 'Func'. Большое спасибо. – Xantham

+0

Хорошо. Читайте о 'Func' и' Action'. –

1

Я думаю, что вы делаете это слишком сложно. Вы можете использовать метод как это:

double bothFunctions(List<Point> PointList, bool sumX) 
{ 
    double sum = 0.0; 
    foreach(Point p in PointList) 
    { 
     if (sumX) 
      sum += p.x; 
     else 
      sum += p.y; 
    }  
    return sum; 
} 

Или просто использовать LINQ:

var ySum = pointList.Sum(e => e.y); 
var xSum = pointList.Sum(e => e.x); 
3

Вы должны смотреть на использовании метода Enumerable.Sum расширения вместо того, чтобы писать свои собственные.

var sumX = pointList.Sum(item => item.X); 
var sumY = pointList.Sum(item => item.Y); 

Вам нужно будет добавить using System.Linq; если уже нет в вашем файле кода.