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

7

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

谢谢


你说的“使用lambda表达式”是指作为过滤器而不是startDate/endDate吗?那么请参考Tim Robinson的回答。否则,请详细说明。 - Lucas
这对我来说也不清楚。我怀疑Tim和其他人的回答可能是他想表达的意思。 - mqp
是的,我需要一个过滤器。不知道该如何正确表达。请根据您的理解修改问题 :) - Th3Fix3r
6个回答

10

您可以使用过滤器来改变示例以使用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);

这个方法最大的优点是灵活性。 相比于基于日期进行过滤计算的方法,您现在可以使用具有灵活过滤器方法来计算百分比的方法。

5

您是否希望使用单个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;
    }

2
你的方法已经隐式地使用了lambda表达式。
当你说:
trade.TradeTime >= startDate

你实际想表达的是“给定名为‘trade’的Trade,通过评估以下内容返回一个 bool 值:trade.TradeTime >= startDate。”

这是该 Lambda 表达式的定义:

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

实际上,如果你使用LINQ的函数组合语法而不是查询语法,那么除了expr的声明外,这就是你表达它的方式。


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

0

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

0

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

我建议阅读Jon Skeet的《C#深入》。它详细介绍了这些主题。

这是将此函数作为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;
            };
        }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接