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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/852916/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-05 04:13:41  来源:igfitidea点击:

How to create extension methods with lambda expressions

c#lambda

提问by

Currently i am creating an extension method that accepts parameters. Using the below example, how could one convert this using 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;
}

What are the pro/cons using lambda vs normal method parameters?

使用 lambda 与普通方法参数的优缺点是什么?

Thanks

谢谢

采纳答案by JaredPar

One way you could change the sample to use lambda expressions is to use a filter.

将示例更改为使用 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);

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.

这给您带来的最大好处是灵活性。而不是使用基于日期的过滤进行计算的方法。您有一种具有灵活过滤方法的方法来计算百分比。

回答by mqp

Your method is implicitly using lambda expressions already.

您的方法已经隐式地使用了 lambda 表达式。

When you say

当你说

trade.TradeTime >= startDate

What you're really saying is "given a Tradecalled "trade", return a boolby evaluating the following: trade.TradeTime >= startDate."

你真正要说的是“给定一个Trade叫” trade“,bool通过评估以下内容返回一个:” trade.TradeTime >= startDate

That is the definition of this lambda expression:

这是这个 lambda 表达式的定义:

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.

事实上,减去 的声明expr,如果您使用 LINQ 的函数组合语法而不是查询语法,这就是表达它的方式。

回答by Tim Robinson

Did you want to replace the startDateand endDateparameters with a single lambda expression?

您想用单个 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;
    }

回答by Amy B

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

回答by bruno conde

Continuing on Tim's answer, you could also provide a lambda to perform the calculation:

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

Usage:

用法:

    trades.ChangePercentage(
        trade => (trade.TradeTime >= startDate && trade.TradeTime <= endDate), 
        (t1, t2) => (t1.Value - t2.Value) / t1.Value * 100
    ); 

回答by Steve

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.

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

I would recommend picking up a copy of Jon Skeet's C# In Depth. It covers these topics in detail.

我建议你拿起一份 Jon Skeet 的 C# In Depth。它详细介绍了这些主题。

Here's this function as a lambda expression

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