繁体   English   中英

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

[英]How to create extension methods with lambda expressions

目前我正在创建一个接受参数的扩展方法。 使用下面的示例,如何使用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方法参数的优缺点是什么?

谢谢

更改样本以使用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);

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

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

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;
    }

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

当你说

trade.TradeTime >= startDate

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

这是lambda表达式的定义:

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

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

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

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
);

继续Tim的回答 ,您还可以提供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
    ); 

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

我建议你拿一份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;
            };
        }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM