如何使用lambda表达式创建扩展方法

时间:2009-05-12 13:55:10

标签: c# lambda

目前我正在创建一个接受参数的扩展方法。使用下面的示例,如何使用lambda表达式转换它?

public static decimal ChangePercentage(this IEnumerable<Trade> trades, DateTime startDate, DateTime endDate)
{
    var query = from trade in trades
                where trade.TradeTime >= startDate
                where trade.TradeTime <= endDate
                orderby trade.TradeTime descending
                select trade;
    return (query.First().Value - query.Last().Value) / query.First().Value * 100;
}

使用lambda vs normal方法参数的优缺点是什么?

由于

6 个答案:

答案 0 :(得分:8)

您可以更改样本以使用lambda表达式的一种方法是使用过滤器。

public static decimal ChangePercentage(this IEnumerable<Trade> trades, 
                                       Func<Trade,bool> pred)
        {
            var query = from trade in trades
                        where pred(trade);
                        orderby trade.TradeTime descending
                        select trade;
            return (query.First().Value - query.Last().Value) / query.First().Value * 100;
        }

    someTrades.ChangePercentage(x => x.TradeDate >= startDate && x.TradeTime <= endDate);

这给你的最大专业是灵活性。而不是使用基于日期过滤进行计算的方法。您有一种方法,使用灵活的过滤方法来计算百分比。

答案 1 :(得分:5)

您是否要将startDateendDate参数替换为单个lambda表达式?

public static decimal ChangePercentage(this IEnumerable<Trade> trades, DateTime startDate, DateTime endDate)
{
    return trades.ChangePercentage(trade => trade.TradeTime >= startDate 
        && trade.TradeTime <= endDate);
}

public static decimal ChangePercentage(this IEnumerable<Trade> trades, Func<Trade, bool> filter)
    {
        var query = from trade in trades
                    where filter(trade)
                    orderby trade.TradeTime descending
                    select trade;
        return (query.First().Value - query.Last().Value) / query.First().Value * 100;
    }

答案 2 :(得分:2)

您的方法已隐式使用lambda表达式。

当你说

trade.TradeTime >= startDate

你真正说的是“给Trade名为”trade“,通过评估以下内容返回booltrade.TradeTime >= startDate。”

这是lambda表达式的定义:

Func<Trade, bool> expr = (trade => trade.TradeTime >= startDate);

事实上,减去expr的声明,如果您使用LINQ的函数组合语法而不是查询语法,这就是表达它的方式。

答案 3 :(得分:0)

如果您不想要参数,可以将过滤移到外面。

public static decimal ChangePercentage(this IEnumerable<Trade> trades)
{
  var query = trades.OrderByDescending(t => t.TradeTime);

  if (query.Any())
    return (query.First().Value - query.Last().Value) / query.First().Value * 100;
  else
    return 0;
}

然后,它可以像这样调用:

DateTime startDate, DateTime endDate

decimal answer = ChangePercentage
(
  from trade in trades
  where trade.TradeTime >= startDate
  where trade.TradeTime <= endDate
  select trade
);

答案 4 :(得分:0)

继续Tim's answer,您还可以提供lambda来执行计算:

    public static decimal ChangePercentage(
        this IEnumerable<Trade> trades, 
        Func<Trade, bool> filter, 
        Func<Trade, Trade, decimal> calc)
    {
        var query = from trade in trades
                    where filter(trade)
                    orderby trade.TradeTime descending
                    select trade;
        return calc(query.First(), query.Last());
    }

用法:

    trades.ChangePercentage(
        trade => (trade.TradeTime >= startDate && trade.TradeTime <= endDate), 
        (t1, t2) => (t1.Value - t2.Value) / t1.Value * 100
    ); 

答案 5 :(得分:0)

了解Lambda表达式与扩展方法的用途不同非常重要。 Lambda表达式主要用作定义委托实现或函数实现的紧凑语法。 lambda表达式的另一个好处是,您可以在另一个函数体内定义事件处理程序和函数,如果您有一个仅在特定方法中使用的简单函数,则非常有用。只需使用Func&lt;&gt;定义函数即可。或行动&lt;&gt;使用lamda语法键入。

我建议你拿一份Jon Skeet的C#In Depth。它详细介绍了这些主题。

这个函数是一个lambda表达式

private void Form1_Load(object sender, EventArgs e)
        {
            //signature of our function
            Func<IEnumerable<Trade>, DateTime, DateTime, decimal> changePercentage = null;

            //function implemented using lambda expression syntax
            changePercentage += (trades, startDate, endDate) => 
            {
                var query = from trade in trades
                            where trade.TradeTime >= startDate
                            where trade.TradeTime <= endDate
                            orderby trade.TradeTime
                            descending
                            select trade;
                return (query.First().Value - query.Last().Value) / query.First().Value * 100;
            };
        }