威尼斯人线上娱乐

接纳泛型元组替代out与ref形式传参,元组类型

31 3月 , 2019  

 元组Tuple

详解C# Tuple VS ValueTuple(元组类 VS 值元组),

C#
7.0已经出来一段时间了,大家都晓得新特点里面有个对元组的优化:ValueTuple。那里运用详尽的例证详解Tuple
VS
ValueTuple(元组类VS值元组),11分钟让您更领会ValueTuple的补益和用法。

若果你对Tuple丰裕领会,能够直接跳过章节”回看Tuple”,直达章节”ValueTuple详解”,查看值元组的炫丽用法。

 

  大家在付出的时候,都会时常碰着2个问题,如何为逻辑上回来四个指标设计方法签名。平时大家会想到利用out或ref修饰参数,大概麻烦些自个儿设定四个类型内部含有四个Object类型属性来接收三个重回值。那两中方法都不够好,前者让程序难以达成多态(out或ref修饰的参数类型,不可能选择派生类替代),设计走向是面向进程,也难以使用链式编制程序;后者因为具备的回来都Object类型,所以在使用时都要拓展转换来真实的档次。在那种情状下大家能够利用泛型元组类型来处。在.Net
4.0中新增了Tuple与Tuple<T1>、Tuple<T1,T2>、Tuple<T1,……,T7,TRest>。就一蹴即至了地方的题材。

  大家在支付的时候,都会时时境遇三个标题,如何为逻辑上回来三个目的设计方式签名。平常我们会想到利用out或ref修饰参数,大概麻烦些本人设定三个项目内部含有五个Object类型属性来收纳多少个重临值。那两中方法都不够好,前者让程序难以达成多态(out或ref修饰的参数类型,无法运用派生类替代),设计走向是面向进度,也难以使用链式编制程序;后者因为兼具的归来都Object类型,所以在利用时都要实行转换来真实的花色。在那种状态下我们得以运用泛型元组类型来处。在.Net
4.0中新增了Tuple与Tuple<T1>、Tuple<T1,T2>、Tuple<T1,……,T7,TRest>。就缓解了地方的难题。

 

接纳泛型元组替代out与ref形式传参,元组类型。回顾Tuple

Tuple是C# 4.0时出的新特点,.Net Framework 4.0上述版本可用。

元组是一种数据结构,具有特定数量和因素连串。比如设计2个长富组数据结构用于存款和储蓄学生信息,一共包括多个因素,第3个是名字,第③个是年纪,第⑤个是身高。

元组的现实使用如下:

  其泛型元组能够更好的处理4种状态:

  其泛型元组能够更好的拍卖4种景况:

  我们今后选拔的C#语法已经足以知足常常的开发需求,但C#语法还在拓展版本的立异,在制造更加多更理想的语义来让我们利用。那里介绍一下C#5.0里的提供的语法——元组。

1.    怎么样成立元组

默许情形.Net
Framework元组仅帮忙1到七个元组成分,假若有几个成分可能更加多,须要接纳Tuple的嵌套和Rest属性去落成。其余Tuple类提供创设元组对象的静态方法。

  • 行使构造函数创设元组:

var testTuple6 = new Tuple<int, int, int, int, int, int>(1, 2, 3, 4, 5, 6);
Console.WriteLine($"Item 1: {testTuple6.Item1}, Item 6: {testTuple6.Item6}");

var testTuple10 = new Tuple<int, int, int, int, int, int, int, Tuple<int, int, int>>(1, 2, 3, 4, 5, 6, 7, new Tuple<int, int, int>(8, 9, 10));
Console.WriteLine($"Item 1: {testTuple10.Item1}, Item 10: {testTuple10.Rest.Item3}");
  • 采纳Tuple静态方法创设元组,最多辅助多个因素:

var testTuple6 = Tuple.Create<int, int, int, int, int, int>(1, 2, 3, 4, 5, 6);
Console.WriteLine($"Item 1: {testTuple6.Item1}, Item 6: {testTuple6.Item6}");

var testTuple8 = Tuple.Create<int, int, int, int, int, int, int, int>(1, 2, 3, 4, 5, 6, 7, 8);
Console.WriteLine($"Item 1: {testTuple8.Item1}, Item 8: {testTuple8.Rest.Item1}");

Note:那里营造出来的Tuple类型其实是Tuple<int, int, int, int, int,
int, int,
Tuple<int>>,因而testTuple8.Rest取到的数据类型是Tuple<int>,因而要想获取准确值需求取Item1属性。

  ①替代out与ref修饰的参数(即方法包罗多个重回值)。

  ①替代out与ref修饰的参数(即方法包罗多个再次回到值)。

  在C#中定义Tuple对象,转到定义查看,大家会看到如下代码

2.    表示一组数据

一般来说创设三个元组表示一个学员的四个音信:名字、年龄和身高,而不用单独额外创设一个类。

var studentInfo = Tuple.Create<string, int, uint>("Bob", 28, 175);
Console.WriteLine($"Student Information: Name [{studentInfo.Item1}], Age [{studentInfo.Item2}], Height [{studentInfo.Item3}]");

  ②通过单个参数将两个值传递给多个艺术。例如,
Thread.Start(Object) 方法有一个单一参数,能够动用该参数向在运转时线程执行的法子提供二个值。

  ②因此单个参数将七个值传递给四个方法。例如,
Thread.Start(Object) 方法有1个十足参数,能够行使该参数向在运行时线程执行的艺术提供一个值。

 #region 程序集 mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
 // C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6\mscorlib.dll
 #endregion

3.    从章程再次来到八个值

当1个函数需求再次回到三个值的时候,一般景观下得以行使out参数,那里能够用元组代替out完结重回三个值。

static Tuple<string, int, uint> GetStudentInfo(string name)
{
    return new Tuple<string, int, uint>("Bob", 28, 175);
}

static void RunTest()
{
    var studentInfo = GetStudentInfo("Bob");
    Console.WriteLine($"Student Information: Name [{studentInfo.Item1}], Age [{studentInfo.Item2}], Height [{studentInfo.Item3}]");
}

4.    用于单参数方法的多值传递

当函数参数仅是3个Object类型时,能够选取元组达成传递五个参数值。

static void WriteStudentInfo(Object student)
{
    var studentInfo = student as Tuple<string, int, uint>;
    Console.WriteLine($"Student Information: Name [{studentInfo.Item1}], Age [{studentInfo.Item2}], Height [{studentInfo.Item3}]");
}

static void RunTest()
{
    var t = new System.Threading.Thread(new System.Threading.ParameterizedThreadStart(WriteStudentInfo));
    t.Start(new Tuple<string, int, uint>("Bob", 28, 175));
    while (t.IsAlive)
    {
        System.Threading.Thread.Sleep(50);
    }
}

 

即便元组有上述方便使用的办法,然而它也有醒指标阙如:

  • 走访成分的时候只得通过ItemX去做客,使用前须要肯定成分顺序,属性名字没有实际意义,不便利记念;
  • 最多有四个因素,要想更两只可以通过最后壹个要素实行嵌套扩大;
  • Tuple是贰个引用类型,不像任何的简约类型一样是值类型,它在堆上分配空间,在CPU密集操作时或许有太多的创制和分配工作。

因此在C# 7.0中引入了三个新的ValueTuple类型,详见下边章节。

  ③提供对数据集的轻松访问和操作。如一条数据(Tuple)中涵盖八个子数据(Tuple中属性),多条记下合并成了数据集(类型为Tuple的集结)。

  ③提供对数据集的轻松访问和操作。如一条数据(Tuple)中富含七个子数据(Tuple中属性),多条记下合并成了数据集(类型为Tuple的晤面)。

  即该语法在.Net Framework4框架中早已得以支撑了。

ValueTuple详解

ValueTuple是C# 7.0的新特点之一,.Net Framework 4.7之上版本可用。

值元组也是一种数据结构,用于表示一定数量和因素体系,可是是和元组类区别的,首要分化如下:

  • 值元组是协会,是值类型,不是类,而元组(Tuple)是类,引用类型;
  • 值元组成分是可变的,不是只读的,也正是说能够转移值元组中的成分值;
  • 值元组的数量成员是字段不是性质。

值元组的切实可行运用如下:

  ④意味一组数据。例如,元组能够表示数据库中的一条记下,并且其质量能够象征该记录的字段。

  ④意味一组数据。例如,元组可以代表数据库中的一条记下,并且其性质能够表示该记录的字段。

  元组Tuple是一种数据结构,具有一定数量和要素系列。什么意思啊?正是元组是足以储备多样类型的对象,能够想象一下当二个函数拥有四个不等类别的重回值时,咱们除了定义了八个再次回到值以外,还要定义四个out或ref类型再次回到值才能解决这一个要求;当然大家也得以定义五个目的保存多少个重临值。但前几天大家多了三个消除方案,定义重回值为贰个元组,就缓解了全套。

1.    怎么着创设值元组

和元组类一样,.Net
Framework值元组也只协助1到8个元组元素,要是有7个因素或许更加多,必要利用值元组的嵌套和Rest属性去贯彻。别的ValueTuple类能够提供创设值元组对象的静态方法。

  • 运用构造函数创制元组:

var testTuple6 = new ValueTuple<int, int, int, int, int, int>(1, 2, 3, 4, 5, 6);
Console.WriteLine($"Item 1: {testTuple6.Item1}, Item 6: {testTuple6.Item6}"); 

var testTuple10 = new ValueTuple<int, int, int, int, int, int, int, ValueTuple<int, int, int>>(1, 2, 3, 4, 5, 6, 7, new ValueTuple <int, int, int>(8, 9, 10));
Console.WriteLine($"Item 1: {testTuple10.Item1}, Item 10: {testTuple10.Rest.Item3}");
  • 接纳Tuple静态方法营造元组,最多援助两个成分:

var testTuple6 = ValueTuple.Create<int, int, int, int, int, int>(1, 2, 3, 4, 5, 6);
Console.WriteLine($"Item 1: {testTuple6.Item1}, Item 6: {testTuple6.Item6}"); 

var testTuple8 = ValueTuple.Create<int, int, int, int, int, int, int, int>(1, 2, 3, 4, 5, 6, 7, 8);
Console.WriteLine($"Item 1: {testTuple8.Item1}, Item 8: {testTuple8.Rest.Item1}");

留神那里营造出来的Tuple类型其实是Tuple<int, int, int, int, int, int,
int,
Tuple<int>>,因而testTuple8.Rest取到的数据类型是Tuple<int>,因而要想获得准确值需求取Item1属性。

优化分歧:当组织出超过三个要素以上的值元组后,能够动用接下去的ItemX进行走访嵌套元组中的值,对于地方的事例,要拜访第1一个要素,既能够经过testTuple10.Rest.Item3造访,也足以透过testTuple10.Item10来走访。

var testTuple10 = new ValueTuple<int, int, int, int, int, int, int, ValueTuple<int, int, int>>(1, 2, 3, 4, 5, 6, 7, new ValueTuple<int, int, int>(8, 9, 10));
Console.WriteLine($"Item 10: {testTuple10.Rest.Item3}, Item 10: {testTuple10.Item10}");

  如下:展现了2个泛型Tuple的宣示

  如下:展现了二个泛型Tuple的申明

  元组Tuple是足以储备几系列型的数额的。NET Framework 间接帮助具备 1 到
7 成分的元组。
别的,您能够创设由嵌套中的元组对象的元组的七个或八个要素Rest属性Tuple<T1, T2, T3, T4, T5, T6, T7, TRest>对象。

2.    表示一组数据

正如创设二个值元组表示二个上学的小孩子的七个新闻:名字、年龄和身高,而不用单独额外创立一个类。

var studentInfo = ValueTuple.Create<string, int, uint>("Bob", 28, 175);
Console.WriteLine($"Student Information: Name [{studentInfo.Item1}], Age [{studentInfo.Item2}], Height [{studentInfo.Item3}]");
 public class Tuple<T1, T2, T3> : IStructuralEquatable, IStructuralComparable, IComparable
    {
        public Tuple(T1 item1, T2 item2, T3 item3);
        public T1 Item1 { get; }
        public T2 Item2 { get; }
        public T3 Item3 { get; }
    //省略方法的具体实现
        public override bool Equals(object obj);
        public override int GetHashCode();
        public override string ToString();
    //省略对借口的实现
    }
 public class Tuple<T1, T2, T3> : IStructuralEquatable, IStructuralComparable, IComparable
    {
        public Tuple(T1 item1, T2 item2, T3 item3);
        public T1 Item1 { get; }
        public T2 Item2 { get; }
        public T3 Item3 { get; }
    //省略方法的具体实现
        public override bool Equals(object obj);
        public override int GetHashCode();
        public override string ToString();
    //省略对借口的实现
    }

  元组常用八种方法︰

3.    从点子重临多少个值

值元组也足以在函数定义中代替out参数再次回到多少个值。

static ValueTuple<string, int, uint> GetStudentInfo(string name)
{
    return new ValueTuple <string, int, uint>("Bob", 28, 175);
}

static void RunTest()
{
    var studentInfo = GetStudentInfo("Bob");
    Console.WriteLine($"Student Information: Name [{studentInfo.Item1}], Age [{studentInfo.Item2}], Height [{studentInfo.Item3}]");
}

优化分歧:重回值能够不明明钦赐ValueTuple,使用新语法(,,)代替,如(string,
int, uint):

static (string, int, uint) GetStudentInfo1(string name)
{
    return ("Bob", 28, 175);
}

static void RunTest1()
{
    var studentInfo = GetStudentInfo1("Bob");
    Console.WriteLine($"Student Information: Name [{studentInfo.Item1}], Age [{studentInfo.Item2}], Height [{studentInfo.Item3}]");
}

调剂查看studentInfo的档次正是ValueType安慕希组。

优化区别:重回值能够钦点成分名字,方便清楚回忆赋值和访问:

static (string name, int age, uint height) GetStudentInfo1(string name)
{
    return ("Bob", 28, 175);
}

static void RunTest1()
{
    var studentInfo = GetStudentInfo1("Bob");
    Console.WriteLine($"Student Information: Name [{studentInfo.name}], Age [{studentInfo.age}], Height [{studentInfo.height}]");
}

方便回想赋值:

威尼斯人线上娱乐 1

便民访问:

威尼斯人线上娱乐 2

  在.Net4.0以下的版本尽管并未框架自带的泛型元组,可是大家得以团结定义泛型元组(代码结构如上),其品种中的相比较与相等的接口也得以依照需如若否落到实处。

  在.Net4.0以下的版本就算没有框架自带的泛型元组,然而大家得以友善定义泛型元组(代码结构如上),其项目中的比较与相等的接口也能够依据需假使否贯彻。

  1,用来代表一组数据。
例如,2个元组能够代表的数据库记录,并且其组件能够表示每一个字段的笔录。

4.    用于单参数方法的多值传递

当函数参数仅是2个Object类型时,能够选拔值元组完结传递多个值。

static void WriteStudentInfo(Object student)
{
    var studentInfo = (ValueTuple<string, int, uint>)student;
    Console.WriteLine($"Student Information: Name [{studentInfo.Item1}], Age [{studentInfo.Item2}], Height [{studentInfo.Item3}]");
}

static void RunTest()
{
    var t = new System.Threading.Thread(new System.Threading.ParameterizedThreadStart(WriteStudentInfo));
    t.Start(new ValueTuple<string, int, uint>("Bob", 28, 175));
    while (t.IsAlive)
    {
        System.Threading.Thread.Sleep(50);
    }
}

正如分别为out或ref修饰参数使用、泛型元组Tuple<T1,T2>的选择

如下分别为out或ref修饰参数使用、泛型元组Tuple<T1,T2>的采纳

  2,若要提供轻松访问和数据集的操作。

5.    解构ValueTuple

威尼斯人线上娱乐 ,能够通过var (x, y)可能(var x, var
y)来解析值元组成分构造局部变量,同时能够利用标志”_”来忽略不必要的成分。

static (string name, int age, uint height) GetStudentInfo1(string name)
{
    return ("Bob", 28, 175);
}

static void RunTest1()
{
    var (name, age, height) = GetStudentInfo1("Bob");
    Console.WriteLine($"Student Information: Name [{name}], Age [{age}], Height [{height}]");

    (var name1, var age1, var height1) = GetStudentInfo1("Bob");
    Console.WriteLine($"Student Information: Name [{name1}], Age [{age1}], Height [{height1}]");

    var (_, age2, _) = GetStudentInfo1("Bob");
    Console.WriteLine($"Student Information: Age [{age2}]");
}

 

由上所述,ValueTuple使C#变得更简单易用。较Tuple比较根本金和利息益如下:

  • ValueTuple援助函数再次来到值新语法”(,,)”,使代码更简明;
  • 能够给成分命名,方便使用和回想,那里必要留意即使命名了,不过实际上value
    tuple没有定义那样名字的天性只怕字段,真正的名字依旧是ItemX,全部的因素名字都只是陈设性和编写翻译时用的,不是运作时用的(因而注意对该品种的体系化和反系列化操作);
  • 能够应用解构方法更方便地利用部分或任何元组的要素;
  • 值元组是值类型,使用起来比引用类型的元组功用高,并且值元组是有比较艺术的,能够用于比较是或不是等于,详见:

 

[原创小说,转发请表明出处,仅供就学钻研之用,如有错误请留言,如觉得不错请推荐,感谢帮衬]

[原文:]

Tuple VS ValueTuple(元组类 VS 值元组),
C#
7.0已经出去一段时间了,大家都知晓新特点里面有个对元组的优化:ValueTuple。这里运用详尽…

public static float TemperatureOfCity(string cityId, out string cityName)
        {
            //省略数据处理内容
            cityName = "腾冲";
            float temperature = 23.6f;
            return temperature;
        }
public static Tuple<string, float> TemperatureOfCity(string cityId)
        {
            //省略数据处理内容
            string cityName = "腾冲";
            float temperature = 23.6f;
            return new Tuple<string, float>(cityName, temperature);
        }
public static float TemperatureOfCity(string cityId, out string cityName)
        {
            //省略数据处理内容
            cityName = "腾冲";
            float temperature = 23.6f;
            return temperature;
        }
public static Tuple<string, float> TemperatureOfCity(string cityId)
        {
            //省略数据处理内容
            string cityName = "腾冲";
            float temperature = 23.6f;
            return new Tuple<string, float>(cityName, temperature);
        }

  3,out参数 (在 C# 中) 或ByRef参数 (在 Visual Basic 中)。

  只怕您并不期待此类Tuple的概念扰攘了项指标确实意义,幸好C#的设计者也考略到那么些难点,允许大家使用using语句为随意的查封泛型类型声贝拉米(Bellamy)(Nutrilon)个别称。

  只怕您并不指望此类Tuple的定义纷扰了花色的真正含义,万幸C#的设计者也考略到那么些难题,允许大家利用using语句为随机的封闭泛型类型声澳优(Aptamil)个小名。

  4,若要将三个值传递给通过单个参数的法门。
例如,Thread.Start(Object)方法只有一个参数,允许你提供三个线程在运维时执行的措施的值。若是您提供Tuple<T1, T2, T3>对象作为艺术自变量,则足以提供有八个项的数量的线程的起步例程。

using CityTemperature = Tuple<string, float>;
public static Tuple<string, float> TemperatureOfCity(string cityId)
        {
        //省略数据处理内容
            string cityName = "腾冲";
            float temperature = 23.6f;
            return new CityTemperature(cityName, temperature);
        }
using CityTemperature = Tuple<string, float>;
public static Tuple<string, float> TemperatureOfCity(string cityId)
        {
        //省略数据处理内容
            string cityName = "腾冲";
            float temperature = 23.6f;
            return new CityTemperature(cityName, temperature);
        }
 class Program
    {
        static void Main(string[] args)
        {
            var tuple = new Tuple<string, int, int, int>(
                             "Kiba", 00001, 00002,
                             00003);

            Console.WriteLine(tuple.Item1);
            Console.WriteLine(tuple.Item2);
            Console.WriteLine(tuple.Item3);
            Console.WriteLine(tuple.Item4);

            var tupleCalss = new Tuple<A, B>(
                         new A(), new B());
            Console.WriteLine(tupleCalss.Item1.Name);
            Console.WriteLine(tupleCalss.Item2.Name);
            Console.ReadKey();
        }
    }
    public class A
    {
        public string name = "A";

        public string Name { get => name; set => name = value; }
    }
    public class B
    {
        public string Name = "B";
    }
}

  以上即便只详细的列出了泛型元组处理的4中状态的(替代out或ref参数)一种,可是别的3中状态的代码编写都以近似。就不一一明细列出。

  以上即便只详细的列出了泛型元组处理的4中状态的(替代out或ref参数)一种,可是任何3中状态的代码编写都是近似。就不一一明细列出。

输出结果
Kiba
1
2
3
A
B


 

【PS:那里运用的对象框架是.net framework
4.0 ,大家可以观看属性的扬言如下,即4.0一度支撑=>情势的性质设置了。】

 public string name = "A";

 public string Name { get => name; set => name = value; }

C#语法——委托,架构的血液

C#语法——泛型的各类用到

C#语法——await与async的科学打开药情势


注:此小说为原创,欢迎转载,请在小说页面明显地点给出此文链接!
若您觉得那篇小说还不易,请点击下右下角的推荐,至极多谢!


相关文章

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图