Как создать методы расширения лямбда-выражения
В настоящее время я создаю метод расширения, который принимает параметры. Используя приведенный ниже пример, как можно преобразовать это с помощью лямбда-выражения?
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;
};
}