Как создать методы расширения лямбда-выражения

В настоящее время я создаю метод расширения, который принимает параметры. Используя приведенный ниже пример, как можно преобразовать это с помощью лямбда-выражения?

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

каковы pro / cons с использованием параметров лямбда-метода против нормального?

спасибо

6 ответов


один из способов изменить образец для использования лямбда-выражений - использовать фильтр.

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

самый большой профессионал, который это дает вам, - это гибкость. Вместо того, чтобы иметь метод, который делает фильтрацию на основе даты для расчета. У вас есть метод с гибким методом фильтра для вычисления процентов.


вы хотите заменить startDate и endDate параметры с одним лямбда-выражения?

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

ваш метод неявно использует лямбда-выражения уже.

когда вы говорите

trade.TradeTime >= startDate

то, что вы на самом деле говорите: "дано Trade под названием "trade", возвратить bool путем оценки следующего:trade.TradeTime >= startDate."

вот определение этого лямбда-выражения:

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

продолжение Тим, вы также можете предоставить лямбду для выполнения вычисления:

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

важно понимать, что лямбда-выражения служат другой цели, чем методы расширения. Лямбда-выражения используются в основном как компактный синтаксис для определения реализации делегата или выполнения функции. Дополнительное преимущество лямбда-выражений заключается в том, что вы можете определить обработчики событий и функции в теле другой функции, полезные, если у вас есть простая функция, которая используется только в определенном методе. Просто определите функцию, используя Func или Action введите с синтаксисом lamda.

Я бы рекомендовал взять копию C# Джона Скита в глубину. В нем подробно рассматриваются эти темы.

вот эта функция как лямбда-выражение

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