Currently i am creating an extension method that accepts parameters. Using the below example, how could one convert this using lambda expressions?
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;
}
What are the pro/cons using lambda vs normal method parameters?
Thanks
One way you could change the sample to use lambda expressions is to use a filter.
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);
The biggest pro this gives you is flexbility. Instead of having a method which does date based filtering for calculation. You have a method with a flexible filter method for calculating percentages.
Did you want to replace the startDate
and endDate
parameters with a single lambda expression?
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;
}
Your method is implicitly using lambda expressions already.
When you say
trade.TradeTime >= startDate
What you're really saying is "given a Trade
called " trade
", return a bool
by evaluating the following: trade.TradeTime >= startDate
."
That is the definition of this lambda expression:
Func<Trade, bool> expr = (trade => trade.TradeTime >= startDate);
And in fact, minus the declaration of expr
, this is how you would express it if you were using the function composition syntax for LINQ instead of the query syntax.
If you don't want parameters, you can move the filtering outside.
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;
}
Then, it can be called like this:
DateTime startDate, DateTime endDate
decimal answer = ChangePercentage
(
from trade in trades
where trade.TradeTime >= startDate
where trade.TradeTime <= endDate
select trade
);
Continuing on Tim's answer , you could also provide a lambda to perform the calculation:
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());
}
Usage:
trades.ChangePercentage(
trade => (trade.TradeTime >= startDate && trade.TradeTime <= endDate),
(t1, t2) => (t1.Value - t2.Value) / t1.Value * 100
);
It's important to understand that Lambda expressions serve a different purpose than extension methods. Lambda expressions are used primarily as a compact syntax for defining a delegate implementation or function implementaion. An added benefit of lambda expressions is that you can define event handlers and functions within the body of another function, useful if you have a simple function that is used only within a specific method. Just define the function using the Func<> or Action<> type with lamda syntax.
I would recommend picking up a copy of Jon Skeet's C# In Depth. It covers these topics in detail.
Here's this function as a lambda expression
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;
};
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.