我正在尝试为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的工作方式。但我只是无法编译代码。
由于
答案 0 :(得分:6)
根据您的修改,您似乎正在尝试将FindEven
功能添加到Enumerable
课程,但这不会奏效。当您拨打Enumerable.Where
时,如果您没有调用扩展程序方法,则需要调用Enumerable
中定义的实际静态方法。你不能以这种方式扩展那个类,因为扩展方法不能扩展静态方法,而不是它们的用途。他们扩展了实例方法。
调用Enumerable.Where
的代码中的等效内容正在调用Program.FindEven
。那是定义静态方法的地方。扩展方法的神奇之处在于Where
和FindEven
都可用于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();
}
}
}