Tuple VS ValueTuple (clase de tupla VS tupla de valor)

Tuple VS ValueTuple (clase de tupla VS tupla de valor)


C # 4.0 agrega la característica tupla de tupla y C # 7.0 optimiza la tupla: ValueTuple.

Tupla

Tuple es una nueva característica lanzada en C # 4.0 y está disponible en .Net Framework 4.0 y superior.

Una tupla es una estructura de datos con un número y una secuencia específicos de elementos. Por ejemplo, diseñe una estructura de datos triple para almacenar información de los estudiantes, que contenga un total de tres elementos, el primero es el nombre, el segundo es la edad y el tercero es la altura.

El uso específico de las tuplas es el siguiente:

1. Crea una tupla

De forma predeterminada, las tuplas de .Net Framework solo admiten de 1 a 7 elementos de tupla. Si hay 8 elementos o más, debe usar los atributos de anidación y descanso de Tuple para lograrlo. Además, la clase Tuple proporciona métodos estáticos para crear objetos tuple.

  • Crear con 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}");
  • Usar tupla
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. Representar un conjunto de datos

Cree una tupla de la siguiente manera para representar las tres informaciones de un estudiante: nombre, edad y altura, en lugar de crear una clase separada.

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

3. Devuelve varios valores del método

Cuando una función necesita devolver varios valores, en general, puede utilizar el parámetro out. Aquí, puede utilizar tuplas en lugar de out para devolver varios valores.

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. Transferencia de varios valores para el método de un solo parámetro

Cuando el parámetro de función es solo un tipo de objeto, puede utilizar tuplas para pasar varios valores de parámetro.

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

Desventaja

  • Al acceder a un elemento, solo se puede acceder a través de ItemX. El orden de los elementos debe aclararse antes de su uso. El nombre del atributo no tiene un significado práctico y no es conveniente recordarlo;
  • Hay hasta ocho elementos, si desea más, solo puede expandir anidando el último elemento;
  • Tuple es un tipo de referencia, no un tipo de valor como otros tipos simples. Asigna espacio en el montón y puede tener demasiado trabajo de creación y asignación durante las operaciones con uso intensivo de la CPU.

ValueTuple

ValueTuple es una de las nuevas características de C # 7.0, .Net Framework 4.7 y superior están disponibles.

Una tupla de valor también es una estructura de datos que se utiliza para representar un número específico y una secuencia de elementos, pero es diferente de la clase de tupla. Las principales diferencias son las siguientes:

  • Una tupla de valor es una estructura, un tipo de valor, no una clase, y una tupla es una clase, un tipo de referencia;
  • El elemento de la tupla de valor es variable, no de solo lectura, es decir, el valor del elemento en la tupla de valor se puede cambiar;
  • El miembro de datos de la tupla de valor es un campo, no un atributo.

El uso específico de las tuplas de valor es el siguiente:

1. Crea una tupla de valor

Al igual que la clase tupla, la tupla de valor de .Net Framework solo admite de 1 a 7 elementos de tupla. Si hay 8 elementos o más, debe utilizar la anidación de la tupla de valor y el atributo Rest para lograrlo. Además, la clase ValueTuple puede proporcionar métodos estáticos para crear objetos de tupla de valor.

  • Usa el constructor para crear una tupla:
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}");
  • Utilice métodos estáticos de tuplas para construir tuplas que admitan hasta ocho elementos:
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属性。

Diferencia de optimización : después de construir una tupla de valor con más de 7 elementos, puede usar el siguiente ItemX para acceder al valor en la tupla anidada. Para el ejemplo anterior, para acceder al décimo elemento, puede pasar testTuple10. Rest.Item3 también puede se puede acceder a través de 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. Representar un conjunto de datos

Cree una tupla de valores de la siguiente manera para representar la información de tres estudiantes: nombre, edad y altura, en lugar de crear una clase adicional separada.

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

3. Devuelve varios valores del método

Las tuplas de valor también pueden devolver varios valores en lugar de parámetros en las definiciones de funciones.

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

Diferencia de optimización : el valor de retorno no se puede especificar claramente ValueTuple, use la nueva sintaxis (,) en su lugar, como (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}]");
}

Depurar para ver que el tipo de studentInfo es el triplete ValueType.

Diferencia de optimización: el valor de retorno puede especificar el nombre del elemento, lo cual es conveniente para comprender la asignación de memoria y el acceso:

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. Transferencia de varios valores para el método de un solo parámetro

Cuando el parámetro de función es solo un tipo de objeto, puede usar una tupla de valor para pasar varios valores.

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

Puede usar var (x, y) o (var x, var y) para analizar los elementos de tupla de valor para construir variables locales, y puede usar el símbolo "_" para ignorar elementos innecesarios.

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

para resumir

De lo anterior, ValueTuple hace que C # sea más fácil de usar. Las principales ventajas sobre Tuple son las siguientes:

  • ValueTuple admite una nueva sintaxis "(,)" para los valores de retorno de la función, lo que simplifica el código;
  • El elemento se puede nombrar para facilitar su uso y memoria. Cabe señalar que, aunque tiene un nombre, la tupla de valor no define realmente un atributo o campo con ese nombre. El nombre real sigue siendo ItemX. Todos los nombres de elementos solo se utilizan durante el diseño y la compilación. No se usa en tiempo de ejecución (así que preste atención a las operaciones de serialización y deserialización de este tipo);
  • Puede usar el método de deconstrucción para usar más convenientemente algunos o todos los elementos de la tupla;
  • La tupla de valor es un tipo de valor, es más eficiente de usar que la tupla de tipo de referencia, y la tupla de valor tiene un método de comparación, que se puede usar para comparar si es igual, consulte: https://msdn.microsoft. com / en- us / library / system.valuetuple.

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

Supongo que te gusta

Origin blog.csdn.net/qq_40513792/article/details/113975002
Recomendado
Clasificación