问题描述
我需要将一个 IEnumerable
和一个委托传递给我的方法,然后对其进行过滤并返回一个包含通过过滤器的数字的 IEnumerable
集合。
Func<int,bool> filter = x => x % 3 == 0;
public static IEnumerable<int> Filter(IEnumerable<int> numbers,Func<int,bool> filter)
{
foreach (int number in numbers)
{
if (filter.Invoke(number))
{
// add number to collection
}
}
// return collection
}
我尝试过创建一个这样的新集合:
IEnumerable<int> result = new IEnumerable<int>();
但这是不可能的,因为 IEnumerable
是一个抽象类。
我应该如何创建和返回这个集合?我知道有很多简单的方法可以做到这一点,但找不到任何方法。
解决方法
正如@somebody 指出的那样,正确的做法是使用 yield return
:
public static IEnumerable<int> Filter(IEnumerable<int> numbers,Func<int,bool> filter) {
foreach (int number in numbers) {
if (filter.Invoke(number)) {
yield return number;
}
}
}
当您返回的集合(您返回的 IEnumerable<int>
)被枚举(通过 foreach
或调用 ToList
之类的东西)时,您的代码将被调用以获取第一项。当您到达 yield return
时,将返回第一个数字。当第二次(以及后续的)迭代发生时,代码将继续在 yield return
之后的行上执行。
就其价值而言,您的代码与 LINQ 的 Where
扩展方法为 IEnumerable<T>
所做的几乎一模一样