[C#7] 1.Tuples(元组)
1. 老版本代码
class Program
{
static void Main(string[] args)
{
var fullName = GetFullName(); Console.WriteLine(fullName.Item1);// Item1,2,3不能忍,,,
Console.WriteLine(fullName.Item2);
Console.WriteLine(fullName.Item3);
}
static Tuple<string, string, string> GetFullName() => new Tuple<string, string, string>("first name", "blackheart", "last name");
}
在有些场景下,我们需要一个方法返回一个以上的返回值,微软在.NET 4中引入了Tuple这个泛型类,可以允许我们返回多个参数,每个参数按照顺序被命名为 Item1;Item2,Item3 ,算是部分的解决了我们的问题,但是对于强迫症程序员来说,Item1,2,3的命名简直是不能忍的,,,so,在C#7中,引入了一个新的泛型类型ValueTuple<T>来解决这个问题,这个类型位于一个单独的dll(System.ValueTuple)中,可以通过nuget来引入到你当前的项目中(https://www.nuget.org/packages/System.ValueTuple/)。
2. ValueTuple
不废话,直接看代码:
class Program
{
static void Main(string[] args)
{
var fullName = GetFullName(); Console.WriteLine(fullName.First); // 终于可以不是Item1,2,3了,,,
Console.WriteLine(fullName.Middle);
Console.WriteLine(fullName.Last);
} static (string First, string Middle, string Last) GetFullName() => ("first name", "blackheart", "last name");
}
看出来差别了吗?我们终于可以用更直观的名字来替换掉该死的"Item1,2,3"了,看起来很棒吧。但是貌似我们并没有用到上面我提到的System.ValueTuple,我们翻开编译后的程序集看看:
internal class Program
{
private static void Main(string[] args)
{
ValueTuple<string, string, string> fullName = Program.GetFullName();
Console.WriteLine(fullName.Item1); // 原来你还是Item1,2,3,,,FUCK!!!
Console.WriteLine(fullName.Item2);
Console.WriteLine(fullName.Item3);
} [TupleElementNames(new string[]
{
"First",
"Middle",
"Last"
})]
private static ValueTuple<string, string, string> GetFullName()
{
return new ValueTuple<string, string, string>("first name", "blackheart", "last name");
}
}
不看不知道,一看吓一跳,原来我们的 fullName.First; 编译后居然还是 fullName.Item1 ,真是日了狗了。。。
不同之处在于GetFullName这个方法,编译器把我们简化的语法形式翻译成了 ValueTuple<string, string, string> ,还给加了一个新的Attribute(TupleElementNamesAttribute),然后把我们自定义的非常直观友好的“First”,"Middle","Last"当作元数据给存起来了(如果只是局部使用,则不会添加这样的元数据)。TupleElementNamesAttribute和ValueTuple一样,位于System.ValueTuple的单独dll中。
3. Example
class Program
{
static void Main(string[] args)
{
var range = (first: , end: );
//也可以这样写,效果是一样的,编译后都是没有了first,end的痕迹,,,first和end只是语法层面的障眼法
//(int first, int last) range = (1, 10);
Console.WriteLine(range.first);
Console.WriteLine(range.end); //可以使用var,这种无显示声明一个变量的方式会编译出多余的代码,慎用,不知是不是还未优化好。
(var begin, var end) = (DateTime.Parse("2017-1-1"), DateTime.Parse("2017-12-31"));
Console.WriteLine(begin);
Console.WriteLine(end); //begin,end可以被覆盖重命名为startDate和endDate,但是会有一个编译警告,提示名字被忽略掉了。
//warning CS8123: The tuple element name 'begin' is ignored because a different name is specified by the target type '(DateTime startDate, DateTime endDate)'
//warning CS8123: The tuple element name 'end' is ignored because a different name is specified by the target type '(DateTime startDate, DateTime endDate)‘
(DateTime startDate, DateTime endDate) timeSpan = (begin: DateTime.Parse("2017-1-1"), end: DateTime.Parse("2017-12-31"));
Console.WriteLine(timeSpan.startDate);
Console.WriteLine(timeSpan.endDate);
}
}
look一下编译后的代码:
private static void Main(string[] args)
{
ValueTuple<int, int> range = new ValueTuple<int, int>(, );
Console.WriteLine(range.Item1);
Console.WriteLine(range.Item2);
6 ValueTuple<DateTime, DateTime> expr_3C = new ValueTuple<DateTime, DateTime>(DateTime.Parse("2017-1-1"), DateTime.Parse("2017-12-31"));
7 DateTime item = expr_3C.Item1;
8 DateTime item2 = expr_3C.Item2;
9 DateTime begin = item;
10 DateTime end = item2;
Console.WriteLine(begin);
Console.WriteLine(end);
ValueTuple<DateTime, DateTime> timeSpan = new ValueTuple<DateTime, DateTime>(DateTime.Parse("2017-1-1"), DateTime.Parse("2017-12-31"));
Console.WriteLine(timeSpan.Item1);
Console.WriteLine(timeSpan.Item2);
}
注意 (var begin, var end) = (DateTime.Parse("2017-1-1"), DateTime.Parse("2017-12-31")); 这一行的便宜结果,看起来很是糟糕(上述6-10行红色部分),可能还是编译优化不足的问题吧(release编译也是如此)。
4. 总结
新的语法形式确实直观友好了好多,but,本质依然是借助泛型类型来实现的,同时也需要编译器对新语法形式的支持。
了解了本质是什么东西之后,以后在项目中环境允许的话,就放心大胆的使用吧(类型ValueTuple可以出现的地方,(first,last)这种新语法形式均可以)。
参考:
https://blogs.msdn.microsoft.com/dotnet/2016/08/24/whats-new-in-csharp-7-0/
https://docs.microsoft.com/en-us/dotnet/articles/csharp/tuples
[C#7] 1.Tuples(元组)的更多相关文章
- 白话C#语法新特性之元组
1.元组(Tuples) 元组(Tuple)在4.0 的时候就有了,但元组也有些缺点,如: 1)Tuple 会影响代码的可读性,因为它的属性名都是:Item1,Item2.. . 2)Tuple 还不 ...
- [Python] 03 - Lists, Dictionaries, Tuples, Set
Lists 列表 一.基础知识 定义 >>> sList = list("hello") >>> sList ['h', 'e', 'l', ' ...
- swift语言的学习笔记
swift参考了OC,Rust,Haskell,Ruby,Python,C#等语言的特性.首先,学习这门语言是速学的,我不想浪费太多时间在笔记这门语言和其他语言的哪里不同,特性你自己亲自实践就知道了. ...
- Swift-1-基本概念
// Playground - noun: a place where people can play // 通过代码快速了解swift常用知识,需要一定object-c基础 import UIKit ...
- swift:入门知识之控制流
1.swift语句中的控制流和其他语言大致相同,使用if和switch作为条件控制.使用 for-in.for.while.do-while作为循环. 2.区别之处:小括号不是必须的,但是主体的大括号 ...
- Swift流程控制之循环语句和判断语句详解
Swift提供了所有c类语言的控制流结构.包括for和while循环来执行一个任务多次:if和switch语句来执行确定的条件下不同的分支的代码:break和continue关键字能将运行流程转到你代 ...
- [干货来袭]C#7.0新特性(VS2017可用)
前言 微软昨天发布了新的VS 2017 ..随之而来的还有很多很多东西... .NET新版本 ASP.NET新版本...等等..太多..实在没消化.. 分享一下其实2016年12月就已经公布了的C#7 ...
- C#7.0新特性
前言 微软昨天发布了新的VS 2017 ..随之而来的还有很多很多东西... .NET新版本 ASP.NET新版本...等等..太多..实在没消化.. 分享一下其实2016年12月就已经公布了的C#7 ...
- C#版本和.NET版本以及VS版本的对应关系
C#版本和.NET版本以及VS版本的对应关系 版本 .NET Framework版本 Visual Studio版本 发布日期 特性 C# 1.0 .NET Framework 1.0 Visual ...
- Scala详解
1 快速入门... 4 1.1 分号... 4 1.2 常变量声明... 4 1.2.1 val常量... 4 1.2.2 ...
随机推荐
- jQuery中animate动画第二次点击事件没反应
jQuery中animate动画第二次点击事件没反应 用animate做点击翻页动画时发现第二次点击事件动画没反应,而第一次点击有动画效果,代码如下: 复制代码 代码如下: $(".page ...
- 部署Replica Sets及查看相关配置
MongoDB 支持在多个机器中通过异步复制达到故障转移和实现冗余.多机器中同一时刻只有一台是用于写操作.正是由于这个情况,为MongoDB 提供了数据一致性的保障.担当Primary 角色的机器能把 ...
- Java Swing jpanel paint方法执行两次的问题
Java Swing jpanel paint方法执行两次的问题: 在其他环境下执行了两次,自己测试怎么都是执行了一次,记录一下这个问题:需要后继工作: 可能是进行各种参数设置的时候导致了paint方 ...
- Java高级特性之泛型
首先我们先提出两个问题: 什么是泛型? 为什么要使用泛型?我们先来看看第一个问题什么是泛型.如果你对Java三大特性中的多态性理解的比较透彻的话,泛型就比较好理解了.多态性表示一个对象具备多种状态.比 ...
- 微信小程序t填坑之旅一(接入)
一.小程序简介 小程序是什么? 首先"程序"这两个字我们不陌生.看看你手机上的各个软件,那就是程序.平时的程序是直接跑在我们原生的操作系统上面的.小程序是间接跑在原生系统上的.因为 ...
- Android项目实战(二十九):酒店预定日期选择
先看需求效果图: 几个需求点: 1.显示当月以及下个月的日历 (可自行拓展更多月份) 2.首次点击选择"开始日期",再次点击选择"结束日期" (1).如果&qu ...
- office如何去除多页签
写文档会遇到同时打开多个文档,偶尔可能需要对比,而有时office会出现跟浏览器类似的多页签界面.如何去除多页签,office本身没有此加载项,一般都是作为插件或组件形式另外安装,导致我们不知道从哪里 ...
- bzoj1061--线性规划
线性规划裸题... 根据题目很容易可以得到线性规划方程(以样例为例): Min(2*x1+5*x2+2*x3) x1+ 0+ 0>=2 x1+x2+ 0>=3 0+x2+x3>=4 ...
- Hadoop权威指南:HDFS-Hadoop存档
Hadoop权威指南:HDFS-Hadoop存档 [TOC] 每个文件按块方式存储, 每个块的元数据存储在namenode的内存中 Hadoop存档文件或HAR文件是一个更高效的文件存档工具,它将文件 ...
- 无线网络中,使用MDK3把指定的用户或者热点踢到掉线
准备 1:系统环境为ubuntu16.04, 2:需要mdk3, mdk3这个软件需要通过apt安装, 需要kali系统的源 3:需要安装aircrack-ng套件 今天这套东西,可以在未连接上靶机网 ...