文档结构  
翻译进度:已翻译     翻译赏金:0 元 (?)    ¥ 我要打赏
参与翻译: 小吕 (7)

C# 7.0 : Tuples to the Extreme!

大多数开发人员在日常工作中不经常会用到元组,但他们有一些不同的用法。 C#的最新版即将发布,但对元组的改变可能是变得越来越重要,你将有可能看到很多新的”玩法“。

那么什么是元组?

如果我们按照MSDN的描述就是:

元组就是一种由特定数字和元素序列构成的数据结构。下面的列子说明元组是一种数据结构,三元素(称为3-Tuple或者Triple)用来存储标识符,比如第一个元素作为存储人名,第二个元素存储年份,然后第三个元素存储个人年收入。

第 1 段(可获 1.65 积分)

或者再基础点, 你可以把它当成一个类,没有任何实际属性,或者你如果懒得去创建一个类来实现某种行为,可以用这个来实现。

例如,让我们假设你想创建一个类用来存储城市/国家的组合,你可能会用下面的方法:

public class Location  
{
     public string City { get; set; }
     public string State { get; set; }

     public Location(string city, string state)
     {
           City = city;
           State = state;
     }
}

// Example
var location = new Location("Lake Charles","LA");  
// Print out the address
var address = $"{location.City}, {location.State}";  
第 2 段(可获 0.74 积分)

你可以用元组做同样的事情,而且你需要做的描述性工作会明显减少:

var location = new Tuple<string,string>("Lake Charles","LA");  
// Print out the address
var address = $"{location.Item1}, {location.Item2}";  

所以在某些情况下,尤其是快速随性的情况下,元组对象可能是非常实用的。MSDN中也有一些常见的用例,你最好能看看。

那么,C#7.0中的元组有些什么新东西?

嗯,C#7.0引入了一个特性,我知道有不少开发者也一直在询问这个特性:多个返回值。

第 3 段(可获 1.1 积分)

没错,现在你可以像下面展示的那样写代码,不必创建一个类,用元组,或用一系列的ref或out参数:

public (string city, string state) GetCityAndState()  
{
    return ("Lake Charles","Louisiana");
}

这将允许你调用一个单一方法就可以访问他们定义的每个返回值,就像下面所示:

var result = GetCityAndState();  
var city = result.city;  // yields "Lake Charles"  
var state = result.state // yields "Louisiana"  

这些方法返回的多个返回值同样可以根据你的需求用多种方式解构:

第 4 段(可获 0.93 积分)
// Using two explicitly defined return values
(string city, string state) = GetCityAndState();
// Using var as opposed to explicit type definitions
(var city, var state) = GetCityAndState();
// Using a single var declaration for multiple variables
var (city, state) = GetCityAndState();  
// Using existing variables
(city,state) = GetCityAndState();

正如你想象的那样,初始化将大致采用类似的语法:

var location = ("Lake Charles", "Louisiana");  

这个特性,一些流行的编程语言如Python, Scala, Ruby, Go等都已经用了相当长一段时间了,所以希望这对C#来说是一个不错的增加。

第 5 段(可获 0.6 积分)

很酷,但还有吗?

除了刚才展示的这些直观的例子,新增加的ValueTuple对象可以用作引用类型,它可以和返回类型的签名匹配,来确保它是有效的,如下面所示:

public (string city, int population) FindBiggestCityWithPopulation(string state)  
{
    var result = (city: "", population: 0);
    result.city = _someService.GetBiggestCity(state);
    result.population = _someService.GetPopulation(result.city);
    return result;
}

同样,这些新的元组也支持开箱的同步/异步模式:

第 6 段(可获 0.63 积分)
public async Task(string bird, string flower) GetStateBirdAndFlowerAsync(string state)  
{
    var bird = await _someService.GetStateBirdAsync(state);
    var flower = await _someService.GetStateFlower(state);
    return (bird,flower);
}

看看这是怎么来的。

“新”微软开发生态系统的一件绝妙的事情就是它是开源的。不再是重要开发部门在阴暗的、烟雾缭绕的房间里的疯狂决策,而是在GitHub上的透明方案。

如果你想看看是什么对话引导了这个功能,您可以在这里访问多个返回值的建议。 您可能还想看看其它的活跃问题,看看其它的功能能否会很快到来。

第 7 段(可获 1.11 积分)

文章评论