Tuple VS ValueTuple (tuple class VS value tuple)

Tuple VS ValueTuple (tuple class VS value tuple)


C#4.0 adds the feature Tuple tuple, and C#7.0 optimizes the tuple: ValueTuple.

Tuple

Tuple is a new feature released in C# 4.0 and is available in .Net Framework 4.0 and above.

A tuple is a data structure with a specific number and sequence of elements. For example, design a triple data structure to store student information, which contains a total of three elements, the first is the name, the second is the age, and the third is the height.

The specific use of tuples is as follows:

1. Create a tuple

By default, .Net Framework tuples only support 1 to 7 tuple elements. If there are 8 elements or more, you need to use Tuple's nesting and Rest attributes to achieve. In addition, the Tuple class provides static methods for creating tuple objects.

  • Create with constructor
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}");
  • Use 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}");

2. Represent a set of data

Create a tuple as follows to represent the three information of a student: name, age, and height, instead of creating a separate class.

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

3. Return multiple values ​​from the method

When a function needs to return multiple values, in general, you can use the out parameter. Here, you can use tuples instead of out to return multiple values.

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}]");
}
//这里构建出来的Tuple类型其实是Tuple<int, int, int, int, int, int, int, Tuple<int>>,因此testTuple8.Rest取到的数据类型是Tuple<int>,因此要想获取准确值需要取Item1属性。

4. Multi-value transfer for single parameter method

When the function parameter is only an Object type, you can use tuples to pass multiple parameter values.

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

Disadvantage

  • When accessing an element, it can only be accessed through ItemX. The order of the elements needs to be clarified before use. The attribute name has no practical meaning and is inconvenient to remember;
  • There are up to eight elements, if you want more, you can only expand by nesting the last element;
  • Tuple is a reference type, not a value type like other simple types. It allocates space on the heap and may have too much creation and allocation work during CPU-intensive operations.

ValueTuple

ValueTuple is one of the new features of C# 7.0, .Net Framework 4.7 and above are available.

A value tuple is also a data structure used to represent a specific number and sequence of elements, but it is different from the tuple class. The main differences are as follows:

  • A value tuple is a structure, a value type, not a class, and a tuple is a class, a reference type;
  • The element of the value tuple is variable, not read-only, that is to say, the value of the element in the value tuple can be changed;
  • The data member of the value tuple is a field, not an attribute.

The specific use of value tuples is as follows:

1. Create a value tuple

Like the tuple class, the .Net Framework value tuple only supports 1 to 7 tuple elements. If there are 8 elements or more, you need to use the nesting of the value tuple and the Rest attribute to achieve. In addition, the ValueTuple class can provide static methods for creating value tuple objects.

  • Use the constructor to create a tuple:
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}");
  • Use Tuple static methods to construct tuples, supporting up to eight elements:
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属性。

Optimization difference : After constructing a value tuple with more than 7 elements, you can use the next ItemX to access the value in the nested tuple. For the above example, to access the tenth element, you can pass testTuple10. Rest.Item3 can also be accessed through 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. Represent a set of data

Create a value tuple as follows to represent the three information of a student: name, age, and height, instead of creating a separate additional class.

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

3. Return multiple values ​​from the method

Value tuples can also return multiple values ​​instead of out parameters in function definitions.

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

Optimization difference : the return value can not be clearly specified ValueTuple, use the new syntax (,) instead, such as (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}]");
}

Debug to see that the type of studentInfo is the ValueType triplet.

Optimization difference: the return value can specify the name of the element to facilitate understanding of memory assignment and access:

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

4. Multi-value transfer for single parameter method

When the function parameter is only an Object type, you can use a value tuple to pass multiple values.

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. Deconstruct ValueTuple

You can use var (x, y) or (var x, var y) to parse the value tuple elements to construct local variables, and you can use the symbol "_" to ignore unnecessary elements

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

to sum up

From the above, ValueTuple makes C# easier to use. The main advantages over Tuple are as follows:

  • ValueTuple supports a new syntax "(,)" for function return values, which makes the code simpler;
  • The element can be named for easy use and memory. It should be noted that although it is named, the value tuple does not actually define an attribute or field with such a name. The real name is still ItemX. All element names are only used during design and compilation. Is not used at runtime (so pay attention to the serialization and deserialization operations of this type);
  • You can use the destructuring method to more conveniently use some or all of the elements of the tuple;
  • The value tuple is a value type, it is more efficient to use than the reference type tuple, and the value tuple has a comparison method, which can be used to compare whether it is equal, see: https://msdn.microsoft.com/en- us/library/system.valuetuple.

Original: http://www.cnblogs.com/lavender000/p/6916157.html

Guess you like

Origin blog.csdn.net/qq_40513792/article/details/113975002