【问题标题】:How can I use linq extensions without lambda?如何在没有 lambda 的情况下使用 linq 扩展?
【发布时间】:2011-05-25 07:22:15
【问题描述】:

这个例子纯粹是为了学习,否则我会马上使用 Lambda 表达式。

我想尝试在没有 lambda 的情况下使用 Where() 扩展方法,只是为了看看它的外观,但我不知道如何让它编译和正常工作。这个例子没有任何意义,所以不要费心去弄清楚它的任何逻辑。

我基本上只是想知道是否可以在不使用 lambda 的情况下使用扩展方法(仅用于学习目的)以及在代码中的样子。

我感到困惑的是 Where() 条件接受Func<int,bool>,但该方法返回IEnumerable<int>? Func 的定义方式是,它接受一个 int 并返回一个 bool。如果这是Func<int, bool, IEnumberable<string>>,对我来说会更有意义

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Delegates
{
    public class Learning
    {
        /// <summary>
        /// Predicates - specialized verison of Func
        /// </summary>
        public static void Main()
        {
            List<int> list = new List<int> { 1, 2, 3 };

            Func<int, bool> someFunc = greaterThanTwo;
            IEnumerable<int> result = list.Where(someFunc.Invoke(1));

        }


        static IEnumerable<int> greaterThanTwo(int arg, bool isValid)
        {
              return new List<int>() { 1 };
        }

    }
}

更新代码

public class Learning
    {
        /// <summary>
        /// Predicates - specialized verison of Func
        /// </summary>
        public static void Main()
        {
            // Without lambda
            List<int> list = new List<int> { 1, 2, 3 };

            Func<int, bool> someFunc = greaterThanTwo;
            // predicate of type int
            IEnumerable<int> result = list.Where(someFunc);

        }


        static bool greaterThanTwo(int arg, bool isValid)
        {
            return true;
        }

    }

我收到以下错误:

“greaterThanTwo”没有重载匹配委托“System.Func”

【问题讨论】:

标签: c# linq lambda


【解决方案1】:

Where 采用一个函数,该函数接受单个元素(在本例中为 int)作为参数,并以布尔值作为其返回类型。这称为谓词 - 它给出“是”或“否”的答案,可以反复应用于相同类型的元素序列。

你在greaterThanTwo 函数上出错了——它接受两个参数,而不是一个——并返回一个IEnumerable&lt;int&gt;——所以它与Func&lt;int, bool&gt; 完全不兼容。它应该接受 int 并返回 bool - 同样,这是一个谓词(见上文)。

一旦你解决了这个问题,你的另一个问题是Invoke - 没有调用任何东西 - 你正在将一个委托(指针)传递给一个方法,以及内部的胆量Where 将负责在需要时调用它。

试试这个:

static bool greaterThanTwo(int arg)
{
    return (arg > 2);
}

//snip

Func<int, bool> someFunc = greaterThanTwo;
IEnumerable<int> result = list.Where(someFunc);

【讨论】:

  • 我尝试使用 int 作为参数并返回 bool,但它抱怨返回类型不是 IEnumberable。我已经更新了我的示例以使用 Func
  • 哦,我明白了。我没有删除 bool 参数。让我感到困惑的是 Where() 上的返回类型指示 IEnumberable 这就是为什么我使用额外参数制作我的 Func
【解决方案2】:

Func&lt;T, TResult&gt; 的定义定义了一个委托,该委托接受 T 类型的单个参数并返回 TResult 类型的结果。 Linqs Where 子句是针对 IEnumerable&lt;T&gt; 定义的(间接通过扩展方法),并采用 Func&lt;T, bool&gt; 类型的参数(Where 的基本版本),基本上说函数必须采用类型为IEnumerable 并返回 bool 值。

为了让你的例子有效:

bool greaterThanTwo(int arg)
{
    // this needs to be a boolean operation against the arg
    return arg > 2;
}

// and invoke like
list.Where(greaterThanTwo);

【讨论】:

  • 很好的例子!有没有办法以这种方式使用带有 2 个输入参数的方法?
【解决方案3】:

Func&lt;int, bool&gt; 意味着你有一个函数,它接受一个 int,并返回一个 bool。如果你想在你的函数中加入更多的参数,你可以把它们列出来,但是你定义的最后一个泛型类型是那个函数的返回类型。如果你想将它定义为 Func,你的方法应该是这样的,Func&lt;int, bool, IEnumerable&lt;int&gt;&gt; 你的函数应该是这样的。

namespace Delegates
{
    public class Learning
    {
        /// <summary>
        /// Predicates - specialized verison of Func
        /// </summary>
        public static void Main()
        {
            List<int> list = new List<int> { 1, 2, 3 };

            Func<int, bool> someFunc = greaterThanTwo;
            IEnumerable<int> result = list.Where(someFunc);

        }


        static bool greaterThanTwo(int arg)
        {
              return (arg > 2);
        }

    }
}

【讨论】:

  • 你偷了我的推特句柄和我的域名:(我不得不使用@rexmorgan 而不是@rexm
【解决方案4】:

Where() 函数对每个项目执行一次 lambda。如果您想返回,请说List&lt;int&gt;,您将使用提供该功能的Aggregate()。但是Where() 会根据您的 lambda 的布尔返回值自动添加或不添加项目。

【讨论】:

    猜你喜欢
    • 2014-03-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-30
    • 1970-01-01
    • 2022-06-15
    • 2014-05-05
    相关资源
    最近更新 更多