C#为“WhereWithIndex”编写类型签名

本文关键字:类型 WhereWithIndex | 更新日期: 2023-09-27 18:28:43

在看到指定如何使用Linq枚举集合的索引的答案后,我决定编写一个与Where行为相似的扩展方法WhereWithIndex,但输入函数应该有两个参数,项和索引。

示例用法应为:

names = new String[] {"Bob", "Alice", "Luke", "Carol"}
names.WhereWithIndex( (_, index) => index % 2 == 0 ) // -> {"Bob", "Luke"}

我已经能够将这个逻辑内联到我的程序中,它看起来像这样:

iterable
  .Select((item, index) => new {item, index})
  .Where(x => condition(item, index))
  .Select(x => x.item);

但我仍然无法为这种扩展方法提供类型签名。我尝试过:

public static IEnumerable<T> WhereWithIndex(this IEnumerable<T> iterable, Predicate<T, int> condition) {

因为我想要一个任何我不能用intString标记的枚举值作为输入,所以我尝试使用T来表示官方文档中的一般性,条件是谓词,所以我这么说了,但我只是猜测,因为我只能用一个输入来资助谓词的示例。

它给了我一个错误:

Example.cs(22,29): error CS0246: The type or namespace name `T' could     
not be found. Are you missing an assembly reference?

写这种类型的签名有什么想法吗?如果它在C#版本6中更简单,那么最好也提到它。

C#为“WhereWithIndex”编写类型签名

已经有一个版本的Where可以做到这一点。它有这样的签名:

public static IEnumerable<TSource> Where<TSource>(this IEnumerable<TSource> source, Func<TSource, int, bool> predicate);

您的签名只缺少Where旁边的<TSource>。这告诉编译器该函数是一个泛型。加上使用Func<TSource, int, bool>而不是Predicate<T, int>。在C#中,Func<P1, P2, P3, R>是一个取P1、P2、P3并返回R的函数,例如:

public R MyFunction(P1 p1, P2 p2, P3 p3) { ... }

另一方面,Action<P1, P2>是一个接受P1和P2并且不返回任何内容的函数:

public void MyAction(P1 p1, P2 p2) { ... }

请注意,在这些示例中,MyFunctionMyAction不是泛型(P1.P3和R需要是实际类型)。如果你想让它通用,你可以把它改为:

public void MyAction<P1, P2>(P1 p1, P2 p2) { ... }

在这种情况下,P1和P2是任意类型的变量名。