将方法应用于类的成员

Yet*_*uff 2 c#

假设我有一个C#类:

public class Node
{
    public double A { get; set; }
    public double B { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

...和另一个包含该类型对象列表的类:

public Buffer
{
    private List<Node> _nodes;
    ...
}
Run Code Online (Sandbox Code Playgroud)

现在,假设我需要计算_nodes列表中Node对象的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;
    }
}
Run Code Online (Sandbox Code Playgroud)

这里的问题是由SumA()和SumB()实现的基本算法是相同的,但在上面的情况下是重复的.如果Node有更多属性需要求和,或者Sum()是一个更复杂的过程(在我目前正在重构的情况下都是如此),这就更复杂了.

因此,换句话说,是否有一种方法可以使用单个Sum()方法,但是它可以对列表中我需要求和的Node类中的任何一个成员进行操作?

Jon*_*eet 8

您应该向LINQ寻求灵感,并且还要实现,使用委托来表示a Node到a 的投影double.例如,你可以写:

private double SumB(Func<Node, double> selector)
{
    return _nodes.Sum(selector);
}
Run Code Online (Sandbox Code Playgroud)

然后用它作为:

double sumA = Sum(node => node.A);
Run Code Online (Sandbox Code Playgroud)

或者,如果您只是在内部使用它(您的方法当前是私有的),请根本不要使用该方法:

double sumA = _nodes.Sum(node => node.A);
Run Code Online (Sandbox Code Playgroud)

如果你需要课外的调用者才能做到这一点,你可以Sum公开,或者如果你已经_nodes以某种方式暴露(例如IEnumerable<Node>),那么外部代码可以使用:

double sumA = buffer.Nodes.Sum(node => node.A);
Run Code Online (Sandbox Code Playgroud)


Dan*_*rth 7

您可以使用委托来获取要汇总的实际属性.

private double Sum(Func<Node, double> selector)
{
    double sum = 0;

    foreach (Node node in _nodes)
    {
        sum += selector(node);
    }

    return sum;
}
Run Code Online (Sandbox Code Playgroud)

你会这样称呼它:

var sumOfA = Sum(x => x.A);
var sumOfB = Sum(x => x.B);
Run Code Online (Sandbox Code Playgroud)

这是一个通用的答案,适用于每个算法.

但是如果你真的想要对这些值求和,可以使用LINQ:

var sumOfA = _nodes.Sum(x => x.A);
var sumOfB = _nodes.Sum(x => x.B);
Run Code Online (Sandbox Code Playgroud)

这将消除您自己的Sum方法的需要.