2016-04-06 97 views
0

我试图给Enumerable类添加一个扩展。但似乎扩展FindEven()不是由C#编译器挑选的。当我建立,编译吐错误:Enumerable不能正常工作的C#扩展

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

任何我在这里不正确?

[编辑]

我想在这里做的是看到在下面的LINQ的“其中”语句是如何工作的通过制作“去哪儿”,在这种情况下是“FindEven”我自己的版本(我不得不承认一个好名字)。

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

我想,如果我通过在可枚举[从元数据]定义的“去哪儿”替换“FindEven” ......这应该是LINQ的工作方式。但我无法获得编译的代码。

感谢

+0

顺便说一句any1有一个想法,我怎么需要1500声望来创建一个'扩展'标签? – r0ng

+0

对于数据质量真的 - 它会阻止'任何人'在标签之后的标签之后创建标签。 – glosrob

+1

只需将'Enumerable.FindEven'替换为'Program.FindEven'或将其称为实例成员函数'numbers.FindEven'即可。请注意,有一种现有的扩展方法完全符合您所谓的“Where”。 –

回答

6

根据您的编辑,看来你想你的FindEven功能添加到Enumerable类,但是这是行不通的。当你打电话给Enumerable.Where时,你并没有调用扩展方法,而是调用了一个在Enumerable中定义的实际静态方法。你不能以这种方式扩展这个类,因为扩展方法不能扩展静态方法,这不是他们的目的。他们扩展实例方法。

您调用Enumerable.Where的代码中的等效项目调用Program.FindEven。这就是静态方法的定义。扩展方法的神奇之处在于WhereFindEven可用于IEnumerable<int>的实例,无论它们在何处定义。

预编辑

从调用方法的方式,你似乎认为,扩展方法添加到Enumerable类的新的静态方法。它不这样工作。您定义的扩展方法“增加”的方法来的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方法什么都不做 - 它只是将每个整数映射到它自己,这意味着它返回一个与其输入完全等效的枚举。

+0

我没有说清楚我的观点,对不起,我添加了一个[edit]部分。谢谢 – r0ng

+0

@ r0ng我相应地更新了我的答案。 –

+0

我尝试这个的原因是因为这个教程https://www.youtube.com/watch?v=FupRSJe-cc0&index=6&list=PL90AF0EFFEF782D27看来可以这样做。 – r0ng

1

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

只需用

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

更换您的通话还要注意,您创建了一个扩展方法IEnumerable<int>,而不是Enumerable

+1

是不是也选择扩展方法?你告诉他他必须把它称为成员函数。我不确定这是否正确。你可以像普通的静态方法一样调用每个扩展方法。他所做的唯一的错误就是将它称为“Enumerable”。他应该用'Program'来称呼它。 –

+0

我没有清楚表明我的观点,对不起,我添加了一个[edit]部分。谢谢 – r0ng

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(); 
     } 
    } 
} 
+0

我没有说清楚我的观点,对不起,我添加了一个[edit]部分。谢谢 – r0ng

相关问题