BT

如何利用碎片时间提升技术认知与能力? 点击获取答案

C#的未来:元组及匿名结构体

| 作者 Jonathan Allen 关注 530 他的粉丝 ,译者 邵思华 关注 3 他的粉丝 发布于 2015年5月8日. 估计阅读时间: 5 分钟 | Google、Facebook、Pinterest、阿里、腾讯 等顶尖技术团队的上百个可供参考的架构实例!

随着C# 6接近完成,C# 7的开发计划也开始提到了日程上。虽然目前为止,还没有任何可确定的内容,但C#团队已经开始按照“兴趣及预计可行性”将各种提议进行分类。在这个系列文章中,我们将对某些提议进行分析,首先从对元组的语言支持开始。

使用元组的目标是以一种轻量级的方式从一个函数中返回多个值。对元组的良好支持能够消除对out参数的使用,这种参数通常被认为是一种笨重的方案。此外,out参数无法兼容async/await,因此在许多场景中out参数将变得毫无作用。

元组类存在什么问题?

从.NET Framework 4开始,就加入了Tuple(元组)这个类。但是多数开发者都认为这个类只在非常有限的场景中才能够体现出实用性。首先,元组是一个类,这意味着在使用时必须为它分配内存,而这一点会增加内存的压力,并使垃圾回收器的执行周期变得更加频繁。如果要让元组与out参数在性能方面进行竞争,需要将其实现为一个结构体。

第二个问题与API的设计有关,如果你看到了某个返回类型Tuple<int, int>,那么从类型本身你无法了解任何信息。如此一来,在使用这个函数的过程中你至少需要检查文档两次,一次是在编写函数时,另一次则是在代码审查时。如果返回类型能够表现为类似于Tuple<int count, int sum>这样,那么它的实用性将会大大增加。

匿名结构体

考虑一下以下代码:

public (int sum, int count) Tally(IEnumerable<int> values) { ... }
var t = new (int sum, int count) { sum = 0, count = 0 };

在这条提议中,以上每一行代码都将定义一个新的匿名值类型,其中包括sum和count属性。需要注意的是,和匿名类不同,匿名结构体要求你明确地列举出属性的名称与类型。

使用结构体的一个好处在于它们会自动定义Equals和GetHashCode方法。不过也有人会表示默认的实现方式不够高效,编译器应当替换它的实现。

分解元组

关于元组的提议中有一个重要的部分,即应当能够通过一行代码对元组进行分解。考虑一下下面的代码块:

var t = Tally(myValues);
var sum = t.Sum;
var count = t.Count;

使用分解功能,这段代码就能够进行简化:

(var sum, var count) = Tally(myValues);

目前还没有决定是否能够在不定义新变量的提前下对元组进行分组。或者换句话说,能否省略“var”的使用,而代之以某个已经存在的本地变量。

返回元组

关于如何从某个函数中返回元组类型这一点,有两条提议正在考虑中。第一条提议非常容易理解:

return (a, b);

而第二条提议的方式将完全不使用return语句。考虑一下这个示例:

public (int sum, int count) Tally(IEnumerable<int> values)
{
    sum = 0; count = 0;
foreach (var value in values) { sum += value; count++; }
}

隐式创建的本地及返回变量并不是一种新的概念,Visual Basic最初的设计就是这样的,只是在VB 7中引入了返回语句之后,这种方法才逐渐变得不流行了。这种写法也类似于使用out参数的方式。不过,对于许多开发者来说,在函数中看不到返回语句总是让他们感觉有些不安。

其它问题

对元组的支持是一个比看上去还要复杂的主题。虽然本文目前讨论的主要是日常的使用方式,但还有许多细节需要从编译器的作者以及高级使用场景的角度进行处理。

元组是否应该作为可变类型?从性能及便利性的角度考虑,这种选择具有一定实用性,但这有可能让代码变得更容易出错,尤其是在处理多线程的情况下。

元组是否应该跨多个程度集进行统一化?匿名类型并不是统一的,但元组与匿名类型不同,它们可以作为API的一部分向外部暴露。

元组能否被转型为其它元组?表面上看,如果两个元组具有相同的类型结构,但具有不同的属性名称。或者具有相同的属性名称,但属性的类型更宽泛,那么这种转换应该是可以接受的。

如果你将某个具有两个值的元组作为参数传递给某个接受两个参数的函数,那么是否应该将元组进行自动分解(摊平)呢?反过来,你能够“反分解”某个参数对,将其合并为某个元组参数吗?

查看英文原文:C# Futures: Tuples and Anonymous Structs

评价本文

专业度
风格

您好,朋友!

您需要 注册一个InfoQ账号 或者 才能进行评论。在您完成注册后还需要进行一些设置。

获得来自InfoQ的更多体验。

告诉我们您的想法

允许的HTML标签: a,b,br,blockquote,i,li,pre,u,ul,p

当有人回复此评论时请E-mail通知我
社区评论

允许的HTML标签: a,b,br,blockquote,i,li,pre,u,ul,p

当有人回复此评论时请E-mail通知我

允许的HTML标签: a,b,br,blockquote,i,li,pre,u,ul,p

当有人回复此评论时请E-mail通知我

讨论

登陆InfoQ,与你最关心的话题互动。


找回密码....

Follow

关注你最喜爱的话题和作者

快速浏览网站内你所感兴趣话题的精选内容。

Like

内容自由定制

选择想要阅读的主题和喜爱的作者定制自己的新闻源。

Notifications

获取更新

设置通知机制以获取内容更新对您而言是否重要

BT