C# 7.0 新特性1之基于Tuple的“多”返回值方法

原文链接:http://www.cnblogs.com/ylvict/p/5573094.html

回顾
 首先,提出一个问题,C#中,如何使一个方法可返回"多个"返回值?
 我们先来回顾一下C#6.0 及更早版本的做法。 
 在C#中,通常我们有以下4种方式使一个方法返回多条数据。
•使用 KeyValue 组合

static void Main(string[] args)
{
 int int1 = 15;
 int int2 = 25;
 var result = Add_Multiply(int1, int2);
 Console.WriteLine(result.Key);
 Console.WriteLine(result.Value);
}

private static KeyValuePair<int, int> Add_Multiply(int int1, int int2)
{
 var KeyValuePair = new KeyValuePair<int, int>(int1 + int2, int1 * int2);
 return KeyValuePair;
}

•使用 ref/out 参数

•Ref

static void Main(string[] args)
{
 int int1 = 15;
 int int2 = 25;
 int add = 0;
 int multiply = 0;
 Add_Multiply(int1, int2, ref add, ref multiply);
 Console.WriteLine(add);
 Console.WriteLine(multiply);
}

private static void Add_Multiply(int int1, int int2, ref int add, ref int multiply)
{
 add = int1 + int2;
 multiply = int1 * int2;
}

•Out

static void Main(string[] args)
{
 int int1 = 15;
 int int2 = 25;
 int add = 0;
 int multiply = 0;
 Add_Multiply(int1, int2, out add, out multiply);
 Console.WriteLine(add);
 Console.WriteLine(multiply);
}

private static void Add_Multiply(int int1, int int2, out int add, out int multiply)
{
 add = int1 + int2;
 multiply = int1 * int2;
}

•使用 struct 或者 class •struct

struct Result
{
 public int add;
 public int multiply;
}
static void Main(string[] args)
{
 int int1 = 53;
 int int2 = 17;
 var result = Add_Multiply(int1, int2);
 Console.WriteLine(result.add);
 Console.WriteLine(result.multiply);
}

private static Result Add_Multiply(int int1, int int2)
{
 var result = new Result
 {
  add = int1 + int2,
  multiply = int1 * int2
 };
 return result;
}

•class

class Result
{
 public int add;
 public int multiply;
}
static void Main(string[] args)
{
 int int1 = 13;
 int int2 = 27;
 var result = Add_Multiply(int1, int2);
 Console.WriteLine(result.add);
 Console.WriteLine(result.multiply);
}

private static Result Add_Multiply(int int1, int int2)
{
 var result = new Result
 {
  add = int1 + int2,
  multiply = int1 * int2
 };
 return result;
}

•dynamic

static void Main(string[] args)
{
 int int1 = 13;
 int int2 = 27;
 var result = Add_Multiply(int1, int2);
 Console.WriteLine(result.add);
 Console.WriteLine(result.multiply);
}

private static dynamic Add_Multiply(int int1, int int2)
{
 var result = new
 {
  add = int1 + int2,
  multiply = int1 * int2
 };
 return result;
}

•使用 Tuple

static void Main(string[] args)
{
 int int1 = 25;
 int int2 = 28;
 var result = Add_Multiply(int1, int2);
 Console.WriteLine(result.Item1);
 Console.WriteLine(result.Item2);
}

private static Tuple<int, int> Add_Multiply(int int1, int int2)
{
 var tuple = new Tuple<int, int>(int1 + int2, int1 * int2);
 return tuple;
}

Okay, 回顾的废话有些多了。我们来看看C#7.0中的写法
新特性(C#7.0)
 老规矩,先上代码

static void Main(string[] args)
{
 int int1 = 25;
 int int2 = 28;
 var result = Add_Multiply(int1, int2);
 Console.WriteLine($"Add: {result.add}, Multiply: {result.multiply}");
 //(var add, var multiply) = Add_Multiply(int1, int2);
 //Console.WriteLine($"Add: {add}, Multiply: {multiply}");
}
public (int add, int multiply) Add_Multiply(int int1, int int2)
 => (int1 + int2, int1 * int2);

怎么样?比起6.0及以前的C#,有没有一种非常清爽的感觉。
其实只是基于Tuple 做了语法简化的语法糖罢了,只是给人一种多个返回值的错觉。

总结: 
这个特性虽然不是多么振奋人心的变化,但是解决了之前很多码农的一些痒点。 
1. 看看KeyValue对的方式,本来很简单的一个操作,写出来的代码会显得非常的笨拙,取值的时候又根据Key获取。而且,最重要的是,如果不在运行时,外面调用的代码是不知道有那些Key的。 
2. 再说Ref/Out,这种方式应该是传统意义上最流行的写法了。甚至C#7.0的该特性,也无法取缔ref在一定情景下的性质。但至少在ref用于返回值这种情况下,代码体现出的风格明显是和实际逻辑不符合的,明明是返回值,却要以参数的形式进出,非常不合理。 
3. struct和class的方式就不多说了,如果你针对的是一个实体,还能讲得通,但如果本身目的是返回多个相关性不大的数据,专门为方法间传递而加一个本没有用处的Model类或结构,只能说是当时解决方案下的无奈。dynamic虽然从表现形式上没有这种问题,但是存在更坑的问题是,除非在运行时,否则外部调用代码根本不知道方法里传出来什么。 
4. 说到传统的Tuple,其实是和该特性最接近的了,但是看看调用时的*.Item1,*.Item2 。。天知道都是何物。即使在实现方法里,也让人面对这种只见类型不见实际意义的值表示一头雾水。 
最后,解释一下,目前(2016年6月)C#7.0还未正式发布,大家如果想体验部分特性,可以去下载VS15预览版,最终发布的语法可能和本文中提及的有说不同,最新动态请大家关注Roslyn项目。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • 深入理解C♯ 7.0中的Tuple特性

    介绍 Tuple是异类对象的有序序列. 我们经常可以写出返回多个值的方法,所以我们需要创建一个包含多个数据元素的简单结构. 为了支持这些情况,Tuple 被添加到 C#. Tuple 是包含多个字段用来表示数据成员的轻量级数据结构. 如果一个方法返回多个相同类型的数值,那么它可以将这些值存储在一个集合中并返回该集合. 但是如果一个方法需要返回多个不同类型的值呢,C# 提供了一些可选项,比如 Class / Struct,输出参数和 Tuple. 让我们创建一个示例. 我们有一个整数的集合,而且我

  • C# 7.0 新特性1之基于Tuple的“多”返回值方法

    原文链接:http://www.cnblogs.com/ylvict/p/5573094.html 回顾  首先,提出一个问题,C#中,如何使一个方法可返回"多个"返回值?  我们先来回顾一下C#6.0 及更早版本的做法.   在C#中,通常我们有以下4种方式使一个方法返回多条数据. •使用 KeyValue 组合 • static void Main(string[] args) { int int1 = 15; int int2 = 25; var result = Add_Mul

  • AngularJS 2.0新特性有哪些

    AngularJS已然成为Web应用开发世界里最受欢迎的开源JavaScript框架.自成立以来,见证其成功的是惊人的经济增长以及团体的支持与采用--包括个人开发者.企业.社区. Angular已经变成一个构建复杂单页面应用的客户端MVW框架(Model-View-Whatever).它在应用测试和应用编写方面都扮演重要角色,同时简化了开发过程. Angular目前的版本为1.3,该版本稳定,并被谷歌(框架维护者)用于支持众多应用(据估计,在谷歌有超过1600个应用运行于Angular1.2或1

  • Android5.0新特性详解之全新的动画

    在Material Design设计中,为用户与app交互反馈他们的动作行为和提供了视觉上的连贯性.Material主题为控件和Activity的过渡提供了一些默认的动画,在android L上,允许自定义这些动画: Touch feedback 触摸反馈 Circular Reveal 圆形展示 Curved motion 曲线运动 View state changes 视图状态变化 Vector Drawables 矢量图动画 Activity transitions 活动转场 触摸反馈 触

  • 简单了解Spring Framework5.0新特性

    SpringFramework5.0是自2013年12月版本4发布之后SpringFramework的第一个主发行版.SpringFramework项目的领导人JuergenHoeller于2016年7月28日宣布了第一个SpringFramework5.0里程碑版本(5.0M1). 现在,将近一年的时间过去以后,我们期盼已久的RC3版本将于2017年7月18日发行.这是路线图规划中SpringFramework5.0首个GA发行版的最后一次发行. 从高层来看,SpringFramework5.

  • 神经网络API、Kotlin支持,那些你必须知道的Android 8.1预览版和Android Studio 3.0新特性

    谷歌2017发布会更新了挺多内容的,而且也发布了AndroidStudio3.0预览版,一些功能先睹为快. 过去的五个月里, Kotlin一直是我们反复谈论的重点.现在要告诉大家的是,Android Studio 3.0可以将Kotlin添加到您的项目中了.最新版本的Android Studio在支持Java 8语言功能上得到了改进,另外一个亮点是,有了用于Gradle 3.0.0的Android插件. 好,下面步入正文. 曾仅用 55 秒发布会的 Android 8.0 Oreo 在时隔两个月

  • 红帽RedHat 8.0新特性(网络、yum源、Web界面管理等)

    1.Red Hat8 配置静态IP 注意:Red Hat8网络管理默认使用NetworkManager,而不是之前版本的network. 按照之前版本我们一般通过配置文件设置静态IP地址信息,如下: [root@localhost ~]# cd /etc/sysconfig/network-scripts [root@localhost network-scripts]# cp ifcfg-ens160 ifcfg-ens160.bak // 备份一下,要养成习惯 手动添加静态IP地址: [ro

  • C#9.0 新特性简介

    CandidateFeaturesForCSharp9 看到标题,是不是认为我把标题写错了?是的,C# 8.0还未正式发布,在官网它的最新版本还是Preview 5,通往C#9的漫长道路却已经开始.前写天收到了活跃在C#一线的BASSAM ALUGILI给我分享C# 9.0新特性,我在他文章的基础上进行翻译,希望能对大家有所帮助. 这是世界上第一篇关于C#9候选功能的文章.阅读完本文后,你将会为未来可能遇到的C# 9.0新特性做好更充分的准备. 这篇文章基于, C# 9.0候选新特性 原生大小的

  • c# 9.0新特性——模块初始化器

    作者:MarkKang 出处:https://www.cnblogs.com/markkang/ 1 背景动机 关于模块或者程序集初始化工作一直是C#的一个痛点,微软内部外部都有大量的报告反应很多客户一直被这个问题困扰,这还不算没有统计上的客户.那么解决这个问题,还有基于什么样的考虑呢? 在库加载的时候,能以最小的开销.无需用户显式调用任何接口,使客户做一些期望的和一次性的初始化. 当前静态构造函数方法的一个最大的问题是运行时会对带有静态构造函数的类型做一些额外的检查.这是因为要决定静态构造函数

  • MySQL 8.0新特性之隐藏字段的深入讲解

    前言 MySQL 8.0.23 版本增加了一个新的功能:隐藏字段(Invisible Column),也称为不可见字段.本文给大家介绍一下 MySQL 隐藏字段的相关概念和具体实现. 基本概念 隐藏字段需要在查询中进行显式引用,否则对查询而言是不可见的.MySQL 8.0.23 开始支持隐藏字段,在此之前所有的字段都是可见字段. 考虑以下应用场景,假如一个应用程序使用SELECT *语句访问某个表,并且必需持续不断地进行查询,即使我们为该表增加了一个该应用不需要的新字段时也要求能够正常工作.对于

  • SpringBoot 3.0 新特性内置声明式HTTP客户端实例详解

    目录 http interface 什么是声明式客户端 测试使用 1. maven 依赖 2. 创建 Http interface 类型 3. 注入声明式客户端 4. 单元测试调用 http interface http interface 从 Spring 6 和 Spring Boot 3 开始,Spring 框架支持将远程 HTTP 服务代理成带有特定注解的 Java http interface.类似的库,如 OpenFeign 和 Retrofit 仍然可以使用,但 http inte

随机推荐