6.2.2 在 C# 中处理元组的方法

6.2.2 在 C# 中处理元组的方法

 

    在本节中,我们将处理来自第 3 章的泛型 Tuple 类,添加类似于我们刚才在 F# 中看到的功能。清单 6.6 显示了高阶函数 mapFirst 和 mapSecond 的 C# 版本。

 

Listing 6.6 Extension methods for working with tuples (C#)

 

public static class Tuple {
  public static Tuple<B, C> MapFirst<A, B, C>
      (this Tuple<A, C> t, Func<A, B> f) {
    return Tuple.Create(f(t.Item1), t.Item2);
  }
  public static Tuple<C, B> MapSecond<A, B, C>
      (this Tuple<C, A> t, Func<A, B> f) {
    return Tuple.Create(t.Item1, f(t.Item2));
  }
}

 

    这些方法的实现是非常简单的,但我们必须显式指定类型。我们使用相同名字的类型参数,就像在以前的 F# 版本一样,因此,可以比较它们。在 C# 中,类型签名被混入这个实现,这会使代码难以阅读,但我们可以分别看一下类型签名:

 

Tuple<B, C> MapFirst(Tuple<A, C>, Func<A, B>)

 

    这与以前的 F# 签名相对应。可以看到最后一个参数值是函数,它转换 A 类型的值到 B 类型的值,我们将在输入的元组中使用 A 类型,在结果中使用 B 类型。我们还改变了参数的顺序,因此,原始的元组现在是第一个参数值。这是因为,我们想要使用这个方法作为元组的扩展方法,所以,元组必须放在首位。我们还为第一个参数添加了 this 修饰符,告诉编译器,我们想使它成为扩展方法。现在,我们可以使用这个方法,既可以直接,也可以作为扩展方法:

 

var oldPrague = Tuple.Create("Prague", 1188000);
var newPrague1 = Tuple.MapSecond(oldPrague, n =&gt; n + 13195);
var newPrague2 = oldPrague.MapSecond(n =&gt; n + 13195);

 

    直接调用此方法时,代码非常类似于在 F# 中的第一种用法,因为,它调用一个有两个参数值的方法,并其中之一使用 lambda 函数。在 F# 中,我们首先能够使用流运算符来写原始的元组,像你可以在最后一行看到的,扩展方法发挥同样的作用。因为 MapSecond 写成扩展方法,我们可以在 oldPrague 对象上使用点表示法。

    在本节中,我们看到两个有用的高阶函数,用于处理元组,我们确信,你现在能够写其他函数,比如,对元组的两个元素应用相同的操作,等等。在前一章中,讨论过多值之后,我们谈论了选项值,因此,我们将遵循相同模式,现在看一下写高阶函数处理可选值。

你可能感兴趣的:(C#,职场,休闲,功能,处理元组)