元组Tuple

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

C#
7.0已经出来一段时间了,我们都知晓新特色里面有个对元组的优化:ValueTuple。这里运用详尽的例子详解Tuple
VS
ValueTuple(元组类VS值元组),十三分钟让您更了然ValueTuple的裨益和用法。

如若您对Tuple丰裕精晓,能够一贯跳过章节”回看Tuple”,直达章节”ValueTuple详解”,查看值元组的炫丽用法。

 

  大家在付出的时候,都会时不时遇到贰个难题,怎么样为逻辑上回来八个对象设计方法签名。平日大家会想到利用out或ref修饰参数,只怕麻烦些本人设定三个品种内部含有四个Object类型属性来接受多少个重返值。那两中方法都不够好,前者让程序难以达成多态(out或ref修饰的参数类型,不可能动用派生类替代),设计走向是面向进程,也难以使用链式编制程序;后者因为全体的回来都Object类型,所以在运用时都要拓展转换到真实的类型。在那种场地下大家得以动用泛型元组类型来处。在.Net
4.0中新增了Tuple与Tuple<T1>、Tuple<T1,T2>、Tuple<T1,……,T7,TRest>。就一蹴而就了地点的标题。

  我们在支付的时候,都会时常蒙受二个标题,如何为逻辑上回来七个对象设计方法签名。平时大家会想到利用out或ref修饰参数,或然麻烦些自个儿设定2个连串内部含有五个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以上版本可用。

元组是一种数据结构,具有一定数量和因素类别。比如设计三个伊利组数据结构用于存款和储蓄学生音讯,一共包蕴多个成分,第1个是名字,第二个是年纪,第多少个是身高。

元组的现实选用如下:

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

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

  我们明天应用的C#语法已经足以满足普通的付出供给,但C#语法还在展开版本的立异,在创设越来越多更优异的语义来让咱们应用。那里介绍一下C#5.0里的提供的语法——元组。

1.    怎么样创设元组

暗许意况.Net
Framework元组仅支持1到多少个元组成分,如若有7个因素恐怕越多,需求利用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}");
  • 应用泛型元组替代out与ref格局传参,元组类型。行使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.    表示一组数据

正如创立3个元组表示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) 方法有3个单纯参数,能够动用该参数向在运维时线程执行的点子提供2个值。

  ②通过单个参数将三个值传递给3个情势。例如,
Thread.Start(Object) 方法有多个纯净参数,能够动用该参数向在运转时线程执行的方法提供2个值。

 #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是一个引用类型,不像任何的简便类型一样是值类型,它在堆上分配空间,在CPU密集操作时可能有太多的创导和分红工作。

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

  ③提供对数据集的无拘无缚访问和操作。如一条数据(Tuple)中隐含多少个子数据(Tuple中属性),多条记下合并成了数据集(类型为Tuple的集聚)。

  ③提供对数据集的自由自在访问和操作。如一条数据(Tuple)中蕴涵七个子数据(Tuple中属性),多条记下合并成了数据集(类型为Tuple的集纳)。

  即该语法在.Net Framework4框架中早已能够扶助了。

ValueTuple详解

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

值元组也是一种数据结构,用于表示一定数量和因素类别,不过是和元组类分歧的,主要差距如下:

  • 值元组是组织,是值类型,不是类,而元组(Tuple)是类,引用类型;
  • 值元组成分是可变的,不是只读的,也便是说可以变更值元组中的成分值;
  • 值元组的数目成员是字段不是性质。

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

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

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

  元组Tuple是一种数据结构,具有一定数量和要素类别。什么看头啊?正是元组是能够储备几类别型的对象,能够设想一下当3个函数拥有八个例外门类的重临值时,大家除了定义了叁个重返值以外,还要定义多少个out或ref类型重临值才能消除那几个须要;当然我们也足以定义一个目的保存七个再次来到值。但后天我们多了2个消除方案,定义重回值为2个元组,就缓解了上上下下。

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实行走访嵌套元组中的值,对于地点的例子,要拜访第⑨个要素,既能够通过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的扬言

  如下:显示了3个泛型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}]");
}

便民记念赋值:

金沙注册送58 1

惠及访问:

金沙注册送58 2

  在.Net4.0之下的版本尽管尚无框架自带的泛型元组,可是我们得以友善定义泛型元组(代码结构如上),其项目中的比较与相等的接口也足以根据需借使否落到实处。

  在.Net4.0以下的版本即便尚未框架自带的泛型元组,不过我们得以友善定义泛型元组(代码结构如上),其项目中的比较与相等的接口也得以依照需如果否落到实处。

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

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

当函数参数仅是贰个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}]");
}

金沙注册送58, 

由上所述,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语句为专断的封闭泛型类型注明二个小名。

  可能你并不指望此类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地图