假设我有一个C#类:
public class Node
{
public double A { get; set; }
public double B { get; set; }
}...and包含该类型对象列表的另一个类:
public Buffer
{
private List<Node> _nodes;
...
}现在,假设我需要计算_nodes列表中节点对象的A的值的总和。然后(单独)计算B的和。有没有一种方法可以用一个‘泛型’Sum()方法来实现,而不需要重复代码?
例如,一种方法可以是:
public class Buffer
{
...
private double SumA()
{
double sum;
foreach (Node node in _nodes)
{
sum += node.A;
}
return sum;
}
private double SumB()
{
double sum;
foreach (Node node in _nodes)
{
sum += node.B;
}
return sum;
}
}这里的问题是,SumA()和SumB()实现的基本算法是相同的,但在上面的情况下是重复的。如果Node有更多的属性,需要求和,或者如果Sum()是一个复杂得多的过程(在我目前正在重构的情况下,这两个过程都是正确的),这一点就会变得复杂起来。
因此,换一种方式来说,有没有办法让我只有一个Sum()方法,但让它对列表中需要求和的Node类的任何成员进行操作?
发布于 2013-05-16 21:22:58
您可以使用委托来获取要汇总的实际属性。
private double Sum(Func<Node, double> selector)
{
double sum = 0;
foreach (Node node in _nodes)
{
sum += selector(node);
}
return sum;
}你可以这样称呼它:
var sumOfA = Sum(x => x.A);
var sumOfB = Sum(x => x.B);这是一个通用的答案,适用于所有算法。
但是如果你真的只想对这些值求和,你可以使用LINQ:
var sumOfA = _nodes.Sum(x => x.A);
var sumOfB = _nodes.Sum(x => x.B);这将消除对您自己的Sum方法的需要。
发布于 2013-05-16 21:23:51
您应该从LINQ中获得灵感,也可以从LINQ中获得实现,它使用委托来表示Node到double的投影。例如,您可以这样写:
private double SumB(Func<Node, double> selector)
{
return _nodes.Sum(selector);
}然后使用它作为:
double sumA = Sum(node => node.A);或者,如果您只在内部使用它(您的方法当前是私有的),则根本不需要为该方法操心:
double sumA = _nodes.Sum(node => node.A);如果你需要类外的调用者能够做到这一点,你可以将你的Sum设置为公共的,或者如果你已经以某种方式公开了_nodes (例如,作为IEnumerable<Node>),那么外部代码可以使用:
double sumA = buffer.Nodes.Sum(node => node.A);发布于 2013-05-16 21:25:46
使用LINQ,您可以将总和简化到一个复制非常小的点:
double sumA = _nodes.Sum(node => node.A);
double sumB = _nodes.Sum(node => node.B);如果你想隐藏_nodes,但却公开了一个sum方法,你可以这样做:
private double Sum(Func<Node, double> selector)
{
return _nodes.Sum(selector);
}https://stackoverflow.com/questions/16588631
复制相似问题