3.2.1.2 在 C# 中使用元组
我们说过,如果使用 .NET 4.0,可以使用现成的泛类型,Tuple<T1, T2>,来自 System 命名空间。我们要看一下如何实现类似的简单类型。
在任何情况下,我们将使用的类型有一个构造函数,它有两个参数,类型分别是 T1 和 T2;不像在 F# 中,可以用函数 fst 和 snd 访问元素,因此,在 C# 中,还有两个属性用于访问成员的值,我们将使用属性 Item1 和 Item2。清单 3.6 的功能现与 3.5 相同,只是用 C# 写的。
清单 3.6 使用元组 (C#)
void PrintCity(Tuple<string, int>cityInfo) {
Console.WriteLine("Population of {0} is {1}.", [1]
cityInfo.Item1, cityInfo.Item2); [2]
}
var prague = new Tuple<string,int>("Prague", 1188000); | [3]
var seattle = new Tuple<string,int>("Seattle", 582000); |
PrintCity(prague); | [4]
PrintCity(seattle); |
把 F# 代码翻译成 C# 是简单的,只要在 C# 中有一个相当于 F# 的元组类型就可以了。PrintCity 方法有一个元组(string 和 int)参数。在 C# 中,必须显式指定方法的参数类型,所以,可以看到 cityInfo 参数的类型是元组 Tuple<string, int>[1]。这个方法用 .NET 的Console.WriteLine 方法输出信息,使用元组类型的属性(Item1 和 Item2)读取元组的值[2]。接下来,我们初始化两个元组,使用有两个参数的构造函数[3],来保存有关城市的信息,然后,使用 PrintCity 方法来显示这个信息[4]。
这段代码稍微有点冗长,主要是因为需要多次显式指定类型;在 F# 的示例中,类型推断机制是可以推断所有的类型。稍后,我们会看到,减少 C# 代码中显式声明类型也是可能的。这里,我们使用新的 C# 3.0 功能(var 关键字),它至少在声明 prague 和 seattle 变量时,使用类型推断[3],因为我们要初始化的变量,C# 可以自动从右侧的赋值推断出类型。
就像 F# 代码一样,如果我们声明了一个不兼容的类型(例如,Tuple<string, double>),就不可能把它作为参数传递给PrintCity 方法。这个限制是在 C# 中更明显,因为我们必须为泛型参数 Tuple 显式声明参数类型。