C#扩展名为Enumerable无法正常工作

时间:2016-04-06 05:07:12

标签: c# linq

我正在尝试为Enumerable类添加扩展名。但似乎C#编译器没有选择扩展FindEven()。当我构建时,编译器吐出错误:

CS0117 'Enumerable' does not contain a definition for 'FindEven'

这是我的代码:

namespace ConsoleApp1
{
  static public class Program
  {
    static IEnumerable<int> FindEven(this IEnumerable<int> array, Func<int, bool> predicte)
    {
      foreach (var n in array)
      {
        if (predicte(n))
        {
          yield return n;
        }
      }
    }
    static public void Main(string[] args)
    {
      int[] numbers = new[]{ 1, 2, 3, 4, 5, 6, 7, 8, 9 };

      var result = Enumerable.Select(Enumerable.FindEven(numbers, n => n % 2 == 0), n => n);
      foreach (var output in result)
        Console.WriteLine(output);

      Console.ReadLine();
    }
  }
}

我在这里做错了什么?

[编辑]

我在这里要做的是通过制作我自己的'Where'版本来看看以下LINQ中的'where'语句是如何工作的,在这种情况下是'FindEven'(我不是一个好名字)承认)。

var result = from element in numbers
where element % 2 == 0
select element;

我认为如果我将'FindEven'替换为Enumerable [from metadata]中定义的'Where'......它应该是LINQ的工作方式。但我只是无法编译代码。

由于

3 个答案:

答案 0 :(得分:6)

根据您的修改,您似乎正在尝试将FindEven功能添加到Enumerable课程,但这不会奏效。当您拨打Enumerable.Where时,如果您没有调用扩展程序方法,则需要调用Enumerable中定义的实际静态方法。你不能以这种方式扩展那个类,因为扩展方法不能扩展静态方法,而不是它们的用途。他们扩展了实例方法。

调用Enumerable.Where的代码中的等效内容正在调用Program.FindEven。那是定义静态方法的地方。扩展方法的神奇之处在于WhereFindEven都可用于IEnumerable<int>的实例,无论它们在何处定义。

<强>预修改

从调用方法的方式来看,您似乎相信扩展方法会向Enumerable类添加一个新的静态方法。它不会那样工作。您定义的扩展方法将&#34;添加&#34; IEnumerable<int>的任何实例的方法,因此您的代码将如下所示:

var result = numbers.FindEven(n => n % 2 == 0);

请注意,您的FindEven实际上并不是FindEven - 它只是使用提供的谓词进行查询,这意味着它与内置的LINQ Where完全相同功能。一个合适的FindEven方法是:

static IEnumerable<int> FindEven(this IEnumerable<int> source)
{
    return source.Where(n => n % 2 == 0);
}

这将返回一个懒惰评估的IEnumerable<int>,仅包含偶数。

此外,您的外部Select方法不执行任何操作 - 它只是将每个整数映射到自身,这意味着它返回的枚举完全等同于其输入。

答案 1 :(得分:1)

定义扩展方法时,必须调用它,因为它是this IEnumerable<int> array参数的成员函数

只需用

替换您的通话
var result = Enumerable.Select(numbers.FindEven(n => n % 2 == 0), n => n);

另请注意,您为IEnumerable<int>创建了一个扩展方法,而不是Enumerable

答案 2 :(得分:1)

根据您的编辑,您可以使用Where功能。

namespace ConsoleApp1
{
    static public class Program
    {
        static public void Main(string[] args)
        {
            int[] numbers = new[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 };

            var result = numbers.Where(n => n % 2 == 0);
            foreach (var output in result)
                Console.WriteLine(output);

            Console.ReadLine();
        }
    }
}