Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 为什么IEnumerable没有FindAll或RemoveAll方法?_C#_Linq_Collections_Extension Methods_Ienumerable - Fatal编程技术网

C# 为什么IEnumerable没有FindAll或RemoveAll方法?

C# 为什么IEnumerable没有FindAll或RemoveAll方法?,c#,linq,collections,extension-methods,ienumerable,C#,Linq,Collections,Extension Methods,Ienumerable,在我看来,IList上的许多扩展方法都同样适用于IEnumerable,比如FindAll和RemoveAll 有人能解释它们不存在的原因吗?RemoveAll毫无意义,因为该API上没有Remove etc-但是从3.5开始就有FindAll-但它被称为Where: 这相当于: IEnumerable<Foo> source = ... var filtered = from x in source where x.IsActive &&

在我看来,IList上的许多扩展方法都同样适用于IEnumerable,比如FindAll和RemoveAll

有人能解释它们不存在的原因吗?

RemoveAll毫无意义,因为该API上没有Remove etc-但是从3.5开始就有FindAll-但它被称为Where:

这相当于:

IEnumerable<Foo> source = ...
var filtered = from x in source
               where x.IsActive && x.Id == 25
               select x;
For RemoveAll不适用于IEnumerable,因为IEnumerable是只读的。
对于FindAll,请参见Marc的答案。

IEnumerable所做的就是指定有一个可以枚举或迭代的集合。它甚至没有指定集合可以多次迭代,更不用说操作了。因此,任何操纵集合的方法都没有意义。然而,像FindAll这样的方法是有意义的。

Enumerable并不意味着存在一个底层集合,因此您无法知道是否有要从中删除的内容。如果存在基础集合,则不知道它是否支持删除操作

下面是一个枚举奇数的示例方法。如果您可以从enumerable中删除7,会发生什么?它将从何处移除

public IEnumerable<int> GetOddPositiveNumbers()
{
   int i = 0;
   while (true)
   {          
      yield return 2*(i++)+1;
   }
}
您可能要查找的是允许您筛选可枚举项的位置和例外情况。

公平地说,如果您实际需要的是特定集合的零长度版本,则类似IEnumerable.RemoveAll的内容实际上是有意义的。调用它RemoveAll没有意义,因为IEnumerable方法实现不应该修改集合

所以在我的例子中,我有时使用一个自定义扩展方法,我称之为Nil


至于Marc已经指出的FindAll,简称为Where。

感谢您的解释,我现在看到了更多的图片,但我可以接着问两个相关的问题吗:1为什么List实现FindAll以及Where,假设它们是相同的:2为什么ICollection不实现RemoveAll,因为它实现Remove?谢谢Andy@Andy我不认为这有什么原因,但你可以自己写一个扩展方法,看看我的答案。@Andy List得到一个Where,因为它实现了IEnumerable。Re-ICollection:因为向接口添加额外的方法不是一个好主意,但是,在接口上使用扩展方法实现它是完全可能的,感谢这些回复。我认为另一件让我困惑的事情是IEnumerable确实有一个remove方法,但仔细检查它确实有作用different@MarcGravell:关于ICollection,向现有接口添加方法可能不切实际,但是,作为标准集合接口的一部分,RemoveAll比Find或Remove更合理[任何为IsReadOnly返回false的集合都应该能够实现它,没有它就无法实现等效功能]。在可枚举的上下文中,“Remove”只表示不在其上枚举。
public IEnumerable<int> GetOddPositiveNumbers()
{
   int i = 0;
   while (true)
   {          
      yield return 2*(i++)+1;
   }
}
static IEnumerable<T> Nil<T>(this IEnumerable<T> self) {
  yield break;
}