C# 为 WhereWithIndex 编写类型签名
C# writing a type signature for `WhereWithIndex`
在看到指定如何使用 Linq 枚举集合索引的答案后,我决定编写一个扩展方法 WhereWithIndex
,其行为类似于 Where
,但输入函数应该有两个参数,项目和索引。
示例用法应为:
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) {
因为我想输入一个可枚举的任何东西,所以我无法用 int
或 String
标记它,所以我尝试使用 T
来表示通用性 following the official documentation, the condition is a predicate so I stated so. How to express the type of a delegate with 2 arguments further eludes me, I tried using a comma to separate the arguments, but I am just guessing as I could only fund examples of predicates with only one input。
它给我错误:
Example.cs(22,29): error CS0246: The type or namespace name `T' could
not be found. Are you missing an assembly reference?
写这个类型签名有什么想法吗?如果它在 C# 版本 6 中更简单,也可以提及它。
already exists 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和returns R的函数,如:
public R MyFunction(P1 p1, P2 p2, P3 p3) { ... }
另一方面,Action<P1, P2>
是一个接受 P1 和 P2 的函数,但不 return 任何东西:
public void MyAction(P1 p1, P2 p2) { ... }
请注意,在这些示例中,MyFunction
和 MyAction
不是泛型(P1..P3 和 R 需要是实际类型)。如果你想让它通用,你可以把它改成:
public void MyAction<P1, P2>(P1 p1, P2 p2) { ... }
在这种情况下,P1和P2是任意类型的变量名。
在看到指定如何使用 Linq 枚举集合索引的答案后,我决定编写一个扩展方法 WhereWithIndex
,其行为类似于 Where
,但输入函数应该有两个参数,项目和索引。
示例用法应为:
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) {
因为我想输入一个可枚举的任何东西,所以我无法用 int
或 String
标记它,所以我尝试使用 T
来表示通用性 following the official documentation, the condition is a predicate so I stated so. How to express the type of a delegate with 2 arguments further eludes me, I tried using a comma to separate the arguments, but I am just guessing as I could only fund examples of predicates with only one input。
它给我错误:
Example.cs(22,29): error CS0246: The type or namespace name `T' could
not be found. Are you missing an assembly reference?
写这个类型签名有什么想法吗?如果它在 C# 版本 6 中更简单,也可以提及它。
already exists 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和returns R的函数,如:
public R MyFunction(P1 p1, P2 p2, P3 p3) { ... }
另一方面,Action<P1, P2>
是一个接受 P1 和 P2 的函数,但不 return 任何东西:
public void MyAction(P1 p1, P2 p2) { ... }
请注意,在这些示例中,MyFunction
和 MyAction
不是泛型(P1..P3 和 R 需要是实际类型)。如果你想让它通用,你可以把它改成:
public void MyAction<P1, P2>(P1 p1, P2 p2) { ... }
在这种情况下,P1和P2是任意类型的变量名。