簡體   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