运用泛型元组替代out与ref情势传参,元组类型

 元组Tuple

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

C#
7.0已经出去一段时间了,大家都通晓新天性里面有个对元组的优化:ValueTuple。那里运用详尽的事例详解Tuple
VS
ValueTuple(元组类VS值元组),10分钟让你更明白ValueTuple的补益和用法。

运用泛型元组替代out与ref情势传参,元组类型。一经您对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>。就缓解了上面包车型的士题材。

 

回顾Tuple

Tuple是C# 4.0时出的新天性,.Net Framework 4.0以上版本可用。

元组是一种数据结构,具有一定数量和要素系列。比如设计一个安慕希组数据结构用于存款和储蓄学生新闻,一共包括多个要素,第二个是名字,第二个是年龄,第五个是身高。

元组的切实接纳如下:

  其泛型元组能够更好的拍卖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.    表示一组数据

正如创建2个元组表示八个学生的多少个音信:名字、年龄和身高,而不用单独额外成立3个类。

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

  ②透过单个参数将几个值传递给1个办法。例如,
Thread.Start(Object) 方法有3个十足参数,能够运用该参数向在运行时线程执行的法子提供1个值。

  ②经过单个参数将多少个值传递给1个主意。例如,
Thread.Start(Object) 方法有四个纯粹参数,能够选取该参数向在运行时线程执行的艺术提供一个值。

 #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.    从章程重回七个值

当贰个函数需求回到八个值的时候,一般景观下得以运用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.    用于单参数方法的多值传递

当函数参数仅是贰个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是2个引用类型,不像别的的简短类型一样是值类型,它在堆上分配空间,在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类型再次来到值才能消除这一个供给;当然大家也能够定义3个目的保存四个重回值。但今后我们多了3个缓解方案,定义重临值为3个元组,就消除了全体。

1.    怎样成立值元组

和元组类一样,.Net
Framework值元组也只帮忙1到九个元组成分,借使有几个要素大概越多,须要接纳值元组的嵌套和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进行走访嵌套元组中的值,对于地方的事例,要访问第8个要素,既能够因而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}");

  如下:体现了叁个泛型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,用来代表一组数据。
例如,一个元组可以象征的数据库记录,并且其组件能够代表每种字段的记录。

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

当函数参数仅是3个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语句为专断的封闭泛型类型声多美滋(Dumex)(Karicare)个别称。

  只怕您并不指望此类Tuple的概念滋扰了项指标确实意义,辛亏C#的设计者也考略到那些题材,允许大家使用using语句为专断的封闭泛型类型声Bellamy(Bellamy)个别称。

  4,若要将八个值传递给通过单个参数的格局。
例如,Thread.Start(Object)方法唯有八个参数,允许你提供2个线程在运转时执行的法子的值。要是你提供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地图