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

C#默认提供了Pair、Triplet
、Tuple(4.0新长的)这三只元组,在有的稍微的数据结构使用时,我们好免用去声明相应的数据结构,而因此这些元组来代表。

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

C#
7.0已经出一段时间了,大家还清楚新特点里面来个对元组的优化:ValueTuple。这里运用详尽的例子详解Tuple
VS
ValueTuple(元组类VS值元组),10分钟为你更了解ValueTuple的益处和用法。

比方您对Tuple足够了解,可以一直跨越了章”回顾Tuple”,直达章节”ValueTuple详解”,查看值元组的炫丽用法。

 

public sealed class Pair
{
    // Fields
    public object First;
    public object Second;

    // Methods
    public Pair()
    {
    }

    public Pair(object x, object y)
    {
        this.First = x;
        this.Second = y;
    }
}

[Serializable]
public sealed class Triplet
{
    // Fields
    public object First;
    public object Second;
    public object Third;

    // Methods
    public Triplet()
    {
    }

    public Triplet(object x, object y)
    {
        this.First = x;
        this.Second = y;
    }

    public Triplet(object x, object y, object z)
    {
        this.First = x;
        this.Second = y;
        this.Third = z;
    }
}

回顾Tuple

Tuple是C# 4.0常常有的初特色,.Net Framework 4.0以上版本可用。

元组是如出一辙种植多少结构,具有一定数量以及因素序列。比如设计一个三元组数据结构用于存储学生信息,一共包含三独要素,第一独凡是名字,第二个是年,第三单凡是身高。

元组的切切实实用如下:

以上这2个东东是象征2单、3单属性之可序列化对象。但是大家一定要是注意它的性质都是object,命名空间是System.Web.UI也就是说它们在System.Web.dll。

1.    如何创造元组

默认情况.Net
Framework元组仅支持1及7单元组元素,如果发生8单要素或更多,需要利用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属性。

在。net4.0中 C#增产了Tuple 可以象征1-8单强类型属性的靶子,在mscorlib.dll的System命名空间下

2.    表示同样组数据

正如创建一个元组表示一个生的老三只消息:名字、年龄及身高,而未用单独额外创建一个像样。

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

 

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中引入了一个初的ValueTuple类型,详见下章节。

public static class Tuple
{
    // Methods
    internal static int CombineHashCodes(int h1, int h2)
    {
        return (((h1 << 5) + h1) ^ h2);
    }

    internal static int CombineHashCodes(int h1, int h2, int h3)
    {
        return CombineHashCodes(CombineHashCodes(h1, h2), h3);
    }

    internal static int CombineHashCodes(int h1, int h2, int h3, int h4)
    {
        return CombineHashCodes(CombineHashCodes(h1, h2), CombineHashCodes(h3, h4));
    }

    internal static int CombineHashCodes(int h1, int h2, int h3, int h4, int h5)
    {
        return CombineHashCodes(CombineHashCodes(h1, h2, h3, h4), h5);
    }

    internal static int CombineHashCodes(int h1, int h2, int h3, int h4, int h5, int h6)
    {
        return CombineHashCodes(CombineHashCodes(h1, h2, h3, h4), CombineHashCodes(h5, h6));
    }

    internal static int CombineHashCodes(int h1, int h2, int h3, int h4, int h5, int h6, int h7)
    {
        return CombineHashCodes(CombineHashCodes(h1, h2, h3, h4), CombineHashCodes(h5, h6, h7));
    }

    internal static int CombineHashCodes(int h1, int h2, int h3, int h4, int h5, int h6, int h7, int h8)
    {
        return CombineHashCodes(CombineHashCodes(h1, h2, h3, h4), CombineHashCodes(h5, h6, h7, h8));
    }

    public static Tuple<T1> Create<T1>(T1 item1)
    {
        return new Tuple<T1>(item1);
    }

    public static Tuple<T1, T2> Create<T1, T2>(T1 item1, T2 item2)
    {
        return new Tuple<T1, T2>(item1, item2);
    }

    public static Tuple<T1, T2, T3> Create<T1, T2, T3>(T1 item1, T2 item2, T3 item3)
    {
        return new Tuple<T1, T2, T3>(item1, item2, item3);
    }

    public static Tuple<T1, T2, T3, T4> Create<T1, T2, T3, T4>(T1 item1, T2 item2, T3 item3, T4 item4)
    {
        return new Tuple<T1, T2, T3, T4>(item1, item2, item3, item4);
    }

    public static Tuple<T1, T2, T3, T4, T5> Create<T1, T2, T3, T4, T5>(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5)
    {
        return new Tuple<T1, T2, T3, T4, T5>(item1, item2, item3, item4, item5);
    }

    public static Tuple<T1, T2, T3, T4, T5, T6> Create<T1, T2, T3, T4, T5, T6>(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6)
    {
        return new Tuple<T1, T2, T3, T4, T5, T6>(item1, item2, item3, item4, item5, item6);
    }

    public static Tuple<T1, T2, T3, T4, T5, T6, T7> Create<T1, T2, T3, T4, T5, T6, T7>(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7)
    {
        return new Tuple<T1, T2, T3, T4, T5, T6, T7>(item1, item2, item3, item4, item5, item6, item7);
    }

    public static Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8>> Create<T1, T2, T3, T4, T5, T6, T7, T8>(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7, T8 item8)
    {
        return new Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8>>(item1, item2, item3, item4, item5, item6, item7, new Tuple<T8>(item8));
    }
}

ValueTuple详解

ValueTuple是C# 7.0之初特点有,.Net Framework 4.7上述版本可用。

值元组也是一模一样种多少结构,用于表示一定数量及因素序列,但是是与元组类非一致的,主要区别如下:

  • 值元组是构造,是值类型,不是近乎,而元组(Tuple)是接近,引用类型;
  • 值元组元素是可变的,不是就念的,也就是说可以更改值元组中的元素值;
  • 值元组的数码成员是字段不是性质。

值元组的有血有肉采用如下:

 

1.    如何创建值元组

以及首组类一样,.Net
Framework值元组也只支持1到7独元组元素,如果起8个元素或另行多,需要动用值元组的嵌套和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属性。

优化区别:当组织出过7单要素以上的价元组后,可以行使接下的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<…>都有[Serializable]特性表示只是序列化。可见Tuple只是一个简约的厂子,使用其可创建Tuple<…>类型的对象了。
至于使用本人哪怕不多说了,个人或建议大家用Tuple而不要使Pair 和Triplet

2.    表示一致组数

如下创建一个值元组表示一个学员的老三独消息:名字、年龄以及身高,而不用单独额外创建一个近似。

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

 

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

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);
    }
}

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,所有的素名字都只是计划和编译时用底,不是运作时用的(因此注意对拖欠项目的序列化和倒序列化操作);
  • 可以使解构方法还便宜地以有还是整元组的元素;
  • 值元组是值类型,使用起来比较引用类型的元组效率高,并且值元组是发较艺术的,可以用来比是否当,详见:https://msdn.microsoft.com/en-us/library/system.valuetuple。

 

[原创文章,转载请注明出处,仅供上钻研之用,如发生误请留言,如觉得对请推荐,谢谢支持]

[原文:http://www.cnblogs.com/lavender000/p/6916157.html,来自永远薰薰\]

http://www.bkjia.com/C\_jc/1213424.htmlwww.bkjia.comtruehttp://www.bkjia.com/C\_jc/1213424.htmlTechArticle详解C\# Tuple VS ValueTuple(元组类 VS 值元组),
C#
7.0已经下一段时间了,大家还知情新特征里面来个对元组的优化:ValueTuple。这里以详尽…

相关文章