我可以用lambda表达式替换多个类似的方法吗?

时间:2014-01-30 05:51:02

标签: c# templates

我有几个函数可以获取对象列表并从中创建一个图表系列。它看起来是重复的,我觉得我可以用Lambda表达式或模板替换这些看似相似的函数,但是却无法弄清楚如何处理每个对象上的不同属性名称。有人可以帮忙吗?

这就是我所拥有的:

private static Series getBuysSeries(List<Order> buys)
{
    var series = new Series();
    foreach (var buy in buys)
    {
        series.Points.AddXY(buy.Price, buy.Quantity);
    }
    return series;
}

private Series getPriceSeries(List<Trade> trades)
{
    var series = new Series();
    foreach (var trade in trades)
    {
        series.Points.AddXY(trade.DateTimeUTC, trade.UnitPrice);

    }
    return series;
}

我认为它看起来像:

private static Series getBuysSeries(List<Order> buys)
{

    return getSeries<Order>(buys);
}

private Series getPriceSeries(List<Trade> trades)
{
    return getSeries<Trade>(trades);
}

private Series getSeries<T>(List<T> list)
{
    ...do the loop but account for property names...
}

1 个答案:

答案 0 :(得分:6)

是的,你可以。至少,你可能会。例如 - 将方法名称更改为更常规,并对方法调用使用泛型类型推断:

private static Series GetBuysSeries(List<Order> buys)
{
    return GetSeries(buys, buy => buy.Price, buy => buy.Quantity);
}

private Series GetPriceSeries(List<Trade> trades)
{
    return getSeries<Trade>(trades,
                            trade => trade.DateTimeUtc,
                            trade => trade.UnitPrice);
}

private Series GetSeries<T>(List<T> list,
                            Func<T, double> selector1,
                            Func<T, double> selector2)
{
    var series = new Series();
    foreach (var item in list)
    {
        series.Points.AddXY(selector1(item), selector2(item));
    }
    return series;
}

现在假设AddXY需要两个double值。 trade.DateTimeUTC似乎有点奇怪,但如果不知道如何定义Series.AddXY,很难提供更具体的建议。

如果您确实想在每种情况下调用AddXY的其他重载,那么它会有点棘手。在这种情况下,您可能需要使用动态类型,例如

private Series GetSeries<T>(List<T> list,
                            Func<T, dynamic> selector1,
                            Func<T, dynamic> selector2)
{
    var series = new Series();
    foreach (var item in list)
    {
        // Here the overload is determined at execution time...
        series.Points.AddXY(selector1(item), selector2(item));
    }
    return series;
}