【问题标题】:C# writing a type signature for `WhereWithIndex`C# 为 `WhereWithIndex` 编写类型签名
【发布时间】:2016-04-06 03:32:18
【问题描述】:

在看到指定如何使用 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) {

因为我想输入一个我无法用intString 标记的任何东西的枚举,所以我尝试使用T 来表示一般性following the official documentation,条件是一个谓词,所以我这么说。如何用 2 个参数表达委托的类型让我更加困惑,我尝试使用逗号分隔参数,但我只是猜测为 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 中更简单,那么也可以提及它。

【问题讨论】:

标签: c# generics collections functional-programming extension-methods


【解决方案1】:

already existsWhere 版本可以做到这一点。它有这个签名:

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

您的签名唯一丢失的是Where 旁边的&lt;TSource&gt;。这告诉编译器该函数是泛型的。加上使用Func&lt;TSource, int, bool&gt; 而不是Predicate&lt;T, int&gt;。在C#中,Func&lt;P1, P2, P3, R&gt;是一个接受P1、P2、P3并返回R的函数,如:

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

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

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

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

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

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

【讨论】:

猜你喜欢
  • 1970-01-01
  • 2022-01-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-01-23
  • 1970-01-01
  • 2022-01-04
  • 1970-01-01
相关资源
最近更新 更多