Tuplas (Visual Basic)Tuples (Visual Basic)

A partir de Visual Basic 2017, el lenguaje Visual Basic ofrece asistencia integrada para las tuplas que permite crear tuplas y acceder a los elementos de tuplas que sea más fácil.Starting with Visual Basic 2017, the Visual Basic language offers built-in support for tuples that makes creating tuples and accessing the elements of tuples easier. Una tupla es una estructura de datos ligero que tiene un número específico y la secuencia de valores.A tuple is a light-weight data structure that has a specific number and sequence of values. Al crear una instancia de la tupla, se definen el número y el tipo de datos de cada valor (o elemento).When you instantiate the tuple, you define the number and the data type of each value (or element). Por ejemplo, una tupla de 2 (o un par) tiene dos elementos.For example, a 2-tuple (or pair) has two elements. Podría ser el primero un Boolean valor, mientras que el segundo es un String.The first might be a Boolean value, while the second is a String. Dado que las tuplas que sea fácil almacenar varios valores en un único objeto, se utilizan a menudo una forma ligera para devolver varios valores de un método.Because tuples make it easy to store multiple values in a single object, they are often used as a lightweight way to return multiple values from a method.

Importante

Compatibilidad con tupla requiere el ValueTuple tipo.Tuple support requires the ValueTuple type. Si no está instalado .NET Framework 4.7, debe agregar el paquete NuGet System.ValueTuple, que está disponible en la Galería de NuGet.If the .NET Framework 4.7 is not installed, you must add the NuGet package System.ValueTuple, which is available on the NuGet Gallery. Sin este paquete, puede aparecer un error de compilación similar a "Tipo predefinido 'ValueTuple(Of,,,)' no está definido o importado."Without this package, you may get a compilation error similar to, "Predefined type 'ValueTuple(Of,,,)' is not defined or imported."

Creación de instancias y uso de una tuplaInstantiating and using a tuple

Crear una instancia de una tupla, incluya sus paréntesis de mensajería instantánea de valores delimitada por comas.You instantiate a tuple by enclosing its comma-delimited values im parentheses. Cada uno de esos valores, a continuación, se convierte en un campo de la tupla.Each of those values then becomes a field of the tuple. Por ejemplo, el código siguiente define un triple (o una tupla de 3) con un Date como su primer valor, un String como el segundo y un Boolean como su tercer.For example, the following code defines a triple (or 3-tuple) with a Date as its first value, a String as its second, and a Boolean as its third.

Dim holiday = (#07/04/2017#, "Independence Day", True)

De forma predeterminada, el nombre de cada campo de una tupla consta de la cadena Item junto con la posición del campo basado en uno de la tupla.By default, the name of each field in a tuple consists of the string Item along with the field's one-based position in the tuple. De esta tupla de 3, el Date campo es Item1, el String campo es Item2y el Boolean campo es Item3.For this 3-tuple, the Date field is Item1, the String field is Item2, and the Boolean field is Item3. El ejemplo siguiente muestra los valores de campos de la tupla que se crea una instancia de la línea de código anteriorThe following example displays the values of fields of the tuple instantiated in the previous line of code

Console.WriteLine($"{holiday.Item1} is {holiday.Item2}" +
                  $"{If(holiday.Item3, ", a national holiday", String.Empty)}")
' Output: 7/4/2017 12:00:00 AM Is Independence Day, a national holiday

Los campos de una tupla de Visual Basic son de lectura y escritura; una vez que haya creado la instancia de una tupla, puede modificar sus valores.The fields of a Visual Basic tuple are read-write; after you've instantiated a tuple, you can modify its values. El ejemplo siguiente modifica dos de los tres campos de la tupla creada en el ejemplo anterior y muestra el resultado.The following example modifies two of the three fields of the tuple created in the previous example and displays the result.

holiday.Item1 = #01/01/2018#
holiday.Item2 = "New Year's Day"
Console.WriteLine($"{holiday.Item1} is {holiday.Item2}" +
                  $"{If(holiday.Item3, ", a national holiday", String.Empty)}")
' Output: 1/1/2018 12:00:00 AM Is New Year's Day, a national holiday

Creación de instancias y uso de una tupla con nombreInstantiating and using a named tuple

En lugar de usar nombres predeterminados para los campos de la tupla, puede crear una instancia de un tupla con nombre mediante la asignación de sus propios nombres a los elementos de la tupla.Rather than using default names for a tuple's fields, you can instantiate a named tuple by assigning your own names to the tuple's elements. Campos de la tupla, a continuación, pueden obtenerse por sus nombres asignados o por sus nombres de forma predeterminada.The tuple's fields can then be accessed by their assigned names or by their default names. El ejemplo siguiente se crea una instancia de la tupla de 3 misma como anteriormente, salvo que nombra explícitamente el primer campo EventDate, el segundo Namey el tercero IsHoliday.The following example instantiates the same 3-tuple as previously, except that it explicitly names the first field EventDate, the second Name, and the third IsHoliday. A continuación, muestra los valores de campo, modifica y muestra los valores de campo nuevo.It then displays the field values, modifies them, and displays the field values again.

Dim holiday = (EventDate:=#07/04/2017#, Name:="Independence Day", IsHoliday:=True)
Console.WriteLine($"{holiday.EventDate} Is {holiday.Name}" +
                  $"{If(holiday.IsHoliday, ", a national holiday", String.Empty)}")
holiday.Item1 = #01/01/2018#
holiday.Item2 = "New Year's Day"
Console.WriteLine($"{holiday.Item1} is {holiday.Item2}" +
                  $"{If(holiday.Item3, ", a national holiday", String.Empty)}")
' The example displays the following output:
'   7/4/2017 12:00:00 AM Is Independence Day, a national holiday
'   1/1/2018 12:00:00 AM Is New Year's Day, a national holiday

Nombres de elementos de tupla inferidosInferred tuple element names

Comenzando con la versión 15.3 de Visual Basic, Visual Basic puede deducir los nombres de elementos de tupla; no es necesario que los asigne explícitamente.Starting with Visual Basic 15.3, Visual Basic can infer the names of tuple elements; you do not have to assign them explicitly. Los nombres de tupla deducidos son útiles al inicializar una tupla a partir de un conjunto de variables y desea que el nombre del elemento de tupla para ser el mismo que el nombre de variable.Inferred tuple names are useful when you initialize a tuple from a set of variables, and you want the tuple element name to be the same as the variable name.

En el ejemplo siguiente se crea un stateInfo tupla que contiene tres explícitamente denominado elementos, state, stateName, y capital.The following example creates a stateInfo tuple that contains three explicitly named elements, state, stateName, and capital. Tenga en cuenta que, en la nomenclatura de los elementos, la instrucción de inicialización de tupla simplemente asigna los elementos con los valores de las variables con el mismo nombre.Note that, in naming the elements, the tuple initialization statement simply assigns the named elements the values of the identically named variables.

Dim state = "MI"
Dim stateName = "Michigan"
Dim capital = "Lansing"
Dim stateInfo = ( state:=state, stateName:=stateName, capital:=capital )
Console.WriteLine($"{stateInfo.stateName}: 2-letter code: {stateInfo.State}, Capital {stateInfo.capital}")   
' The example displays the following output:
'      Michigan: 2-letter code: MI, Capital Lansing

Dado que los elementos y las variables tienen el mismo nombre, el compilador de Visual Basic puede deducir los nombres de los campos, como se muestra en el ejemplo siguiente.Because elements and variables have the same name, the Visual Basic compiler can infer the names of the fields, as the following example shows.

Dim state = "MI"
Dim stateName = "Michigan"
Dim capital = "Lansing"
Dim stateInfo = ( state, stateName, capital )
Console.WriteLine($"{stateInfo.stateName}: 2-letter code: {stateInfo.State}, Capital {stateInfo.capital}")   
' The example displays the following output:
'      Michigan: 2-letter code: MI, Capital Lansing

Para permitir que los nombres de elementos de tupla interred, debe definir la versión del compilador de Visual Basic para usar en su proyecto de Visual Basic (*.vbproj) archivo:To enable interred tuple element names, you must define the version of the Visual Basic compiler to use in your Visual Basic project (*.vbproj) file:

<PropertyGroup> 
  <LangVersion>15.3</LangVersion> 
</PropertyGroup> 

El número de versión puede ser cualquier versión del compilador de Visual Basic, comenzando con la versión 15.3.The version number can be any version of the Visual Basic compiler starting with 15.3. En lugar de codificar una versión específica del compilador, también puede especificar "Latest" como el valor de LangVersion para compilar con la versión más reciente del compilador de Visual Basic instalada en el sistema.Rather than hard-coding a specific compiler version, you can also specify "Latest" as the value of LangVersion to compile with the most recent version of the Visual Basic compiler installed on your system.

Para obtener más información, consulte configuración de la versión de idioma de Visual Basic.For more information, see setting the Visual Basic language version.

En algunos casos, el compilador de Visual Basic no puede inferir el nombre del elemento de tupla desde el nombre del candidato y el campo de tupla solo se puede hacer referencia mediante su nombre predeterminado, como Item1, Item2, etcetera. Se incluyen los siguientes:In some cases, the Visual Basic compiler cannot infer the tuple element name from the candidate name, and the tuple field can only be referenced using its default name, such as Item1, Item2, etc. These include:

  • El nombre del candidato es el mismo que el nombre de un miembro de la tupla, como Item3, Rest, o ToString.The candidate name is the same as the name of a tuple member, such as Item3, Rest, or ToString.

  • El nombre del candidato está duplicado en la tupla.The candidate name is duplicated in the tuple.

Cuando se produce un error en la inferencia de nombre de campo, Visual Basic no genera un error del compilador, ni es una excepción en tiempo de ejecución.When field name inference fails, Visual Basic does not generate a compiler error, nor is an exception thrown at runtime. En su lugar, los campos de tupla deben hacer referencia a sus nombres predefinidos, como Item1 y Item2.Instead, tuple fields must be referenced by their predefined names, such as Item1 and Item2.

Tuplas frente a estructurasTuples versus structures

Una tupla de Visual Basic es un tipo de valor que es una instancia de uno de los un System.ValueTuple tipos genéricos.A Visual Basic tuple is a value type that is an instance of one of the a System.ValueTuple generic types. Por ejemplo, el holiday tupla definida en el ejemplo anterior es una instancia de la ValueTuple<T1,T2,T3> estructura.For example, the holiday tuple defined in the previous example is an instance of the ValueTuple<T1,T2,T3> structure. Está diseñado para ser un contenedor ligero para datos.It is designed to be a lightweight container for data. Dado que el objetivo es la tupla para facilitar la creación de un objeto con varios elementos de datos, carece de algunas de las características que podría tener una estructura personalizada.Since the tuple aims to make it easy to create an object with multiple data items, it lacks some of the features that a custom structure might have. Se incluyen los siguientes:These include:

  • Miembros personalizados.Custom members. No se puede definir sus propias propiedades, métodos o eventos de una tupla.You cannot define your own properties, methods, or events for a tuple.

  • Validación.Validation. No se puede validar los datos asignados a campos.You cannot validate the data assigned to fields.

  • Inmutabilidad.Immutability. Las tuplas de Visual Basic son mutables.Visual Basic tuples are mutable. En cambio, una estructura personalizada le permite controlar si una instancia es mutable o no.In contrast, a custom structure allows you to control whether an instance is mutable or immutable.

Si la inmutabilidad y validación de campos, propiedades o miembros personalizados es importante, debe usar Visual Basic estructura instrucción para definir un tipo de valor personalizado.If custom members, property and field validation, or immutability are important, you should use the Visual Basic Structure statement to define a custom value type.

Una tupla de Visual Basic heredan los miembros de su ValueTuple tipo.A Visual Basic tuple does inherit the members of its ValueTuple type. Además de sus campos, estos incluyen los siguientes métodos:In addition to its fields, these include the following methods:

MiembroMember DescripciónDescription
CompareToCompareTo Compara la tupla actual a otra tupla con el mismo número de elementos.Compares the current tuple to another tuple with the same number of elements.
Es igual aEquals Determina si la tupla actual es igual que otro objeto o tupla.Determines whether the current tuple is equal to another tuple or object.
GetHashCodeGetHashCode Calcula el código hash para la instancia actual.Calculates the hash code for the current instance.
ToStringToString Devuelve la representación de cadena de esta tupla, que tiene la forma (Item1, Item2...), donde Item1 y Item2 representan los valores de campos de la tupla.Returns the string representation of this tuple, which takes the form (Item1, Item2...), where Item1 and Item2 represent the values of the tuple's fields.

Además, el ValueTuple tipos implementan IStructuralComparable y IStructuralEquatable interfaces, que le permiten definir comparadores de cliente.In addition, the ValueTuple types implement IStructuralComparable and IStructuralEquatable interfaces, which allow you to define customer comparers.

Asignación y tuplasAssignment and tuples

Visual Basic admite la asignación entre tipos de tupla que tienen el mismo número de campos.Visual Basic supports assignment between tuple types that have the same number of fields. Los tipos de campo se pueden convertir si se cumple una de las siguientes acciones:The field types can be converted if one of the following is true:

  • El campo de origen y destino son del mismo tipo.The source and target field are of the same type.

  • Se define una conversión de ampliación (o implícita) del tipo de origen al tipo de destino.A widening (or implicit) conversion of the source type to the target type is defined.

  • Option Strict es On, y se define una conversión de restricción (o explícita) del tipo de origen al tipo de destino.Option Strict is On, and a narrowing (or explicit) conversion of the source type to the target type is defined. Esta conversión puede producir una excepción si el valor de origen está fuera del intervalo del tipo de destino.This conversion can throw an exception if the source value is outside the range of the target type.

Otras conversiones no se tienen en cuenta para las asignaciones.Other conversions are not considered for assignments. Echemos un vistazo a los tipos de asignaciones que se permiten entre los tipos de tupla.Let's look at the kinds of assignments that are allowed between tuple types.

Tenga en cuenta estas variables que se usan en los ejemplos siguientes:Consider these variables used in the following examples:

' The number and field types of all these tuples are compatible. 
' The only difference Is the field names being used.
Dim unnamed = (42, "The meaning of life")
Dim anonymous = (16, "a perfect square")
Dim named = (Answer:=42, Message:="The meaning of life")
Dim differentNamed = (SecretConstant:=42, Label:="The meaning of life")

Las dos primeras variables, unnamed y anonymous, no tienen nombres semánticos proporcionados para los campos.The first two variables, unnamed and anonymous, do not have semantic names provided for the fields. Sus nombres de campo son los predeterminados Item1 y Item2.Their field names are the default Item1 and Item2. Las dos últimas variables, named y differentName tienen nombres de campo semántico.The last two variables, named and differentName have semantic field names. Tenga en cuenta que estas dos tuplas tienen nombres diferentes para los campos.Note that these two tuples have different names for the fields.

Todas estas cuatro tuplas tienen el mismo número de campos (denominados "aridad") y los tipos de esos campos son idénticos.All four of these tuples have the same number of fields (referred to as 'arity'), and the types of those fields are identical. Por consiguiente, todas estas asignaciones funcionan:Therefore, all of these assignments work:

' Assign named to unnamed.
named = unnamed

' Despite the assignment, named still has fields that can be referred to as 'answer' and 'message'.
Console.WriteLine($"{named.Answer}, {named.Message}")
' Output:  42, The meaning of life

' Assign unnamed to anonymous.
anonymous = unnamed
' Because of the assignment, the value of the elements of anonymous changed.
Console.WriteLine($"{anonymous.Item1}, {anonymous.Item2}")
' Output:   42, The meaning of life

' Assign one named tuple to the other.
named = differentNamed
' The field names are Not assigned. 'named' still has 'answer' and 'message' fields.
Console.WriteLine($"{named.Answer}, {named.Message}")
' Output:   42, The meaning of life

Observe que los nombres de las tuplas no se asignan.Notice that the names of the tuples are not assigned. Los valores de los campos se asignan según el orden de los campos de la tupla.The values of the fields are assigned following the order of the fields in the tuple.

Por último, tenga en cuenta que podemos asignar el named tupla para el conversion tupla, incluso aunque el primer campo de named es un Integery el primer campo de conversion es un Long.Finally, notice that we can assign the named tuple to the conversion tuple, even though the first field of named is an Integer, and the first field of conversion is a Long. Esta asignación se realiza correctamente porque la conversión de un Integer a un Long es una conversión de ampliación.This assignment succeeds because converting an Integer to a Long is a widening conversion.

' Assign an (Integer, String) tuple to a (Long, String) tuple (using implicit conversion).
Dim conversion As (Long, String) = named
Console.WriteLine($"{conversion.Item1} ({conversion.Item1.GetType().Name}), " +
                  $"{conversion.Item2} ({conversion.Item2.GetType().Name})")
' Output:      42 (Int64), The meaning of life (String)

Las tuplas con distintos números de campos no son asignables:Tuples with different numbers of fields are not assignable:

' Does not compile.
' VB30311: Value of type '(Integer, Integer, Integer)' cannot be converted
'          to '(Answer As Integer, Message As String)'
var differentShape = (1, 2, 3)
named = differentShape

Tuplas como valores devueltos del métodoTuples as method return values

Un método puede devolver un solo valor.A method can return only a single value. Con frecuencia, sin embargo, desea que una llamada al método para devolver varios valores.Frequently, though, you'd like a method call to return multiple values. Hay varias maneras de solucionar esta limitación:There are several ways to work around this limitation:

  • Puede crear una clase personalizada o una estructura cuyas propiedades o campos representan los valores devueltos por el método.You can create a custom class or structure whose properties or fields represent values returned by the method. Por lo tanto, es una solución pesada; requiere que se defina un tipo personalizado cuyo único propósito es recuperar los valores de una llamada al método.Thus is a heavyweight solution; it requires that you define a custom type whose only purpose is to retrieve values from a method call.

  • Puede devolver un único valor desde el método y devolver los valores restantes pasando por referencia al método.You can return a single value from the method, and return the remaining values by passing them by reference to the method. Esto implica la sobrecarga de crear instancias de una variable y los riesgos que se sobrescriba accidentalmente el valor de la variable que se pasa por referencia.This involves the overhead of instantiating a variable and risks inadvertently overwriting the value of the variable that you pass by reference.

  • Puede utilizar una tupla, que proporciona una solución ligera para recuperar varios valores devueltos.You can use a tuple, which provides a lightweight solution to retrieving multiple return values.

Por ejemplo, el TryParse los métodos de devolución de .NET un Boolean valor que indica si la operación de análisis se realizó correctamente.For example, the TryParse methods in .NET return a Boolean value that indicates whether the parsing operation succeeded. Se devuelve el resultado de la operación de análisis en una variable pasada por referencia al método.The result of the parsing operation is returned in a variable passed by reference to the method. Normalmente, una llamada a la un método de análisis como Int32.TryParse el siguiente aspecto:Normally, a call to the a parsing method such as Int32.TryParse looks like the following:

Dim numericString As String = "123456"
Dim number As Integer
Dim result = Int32.TryParse(numericString, number)
Console.WriteLine($"{If(result, $"Success: {number:N0}", "Failure")}")
'      Output: 123,456

Podemos devolvemos una tupla de la operación de análisis si se incluyen la llamada a la Int32.TryParse método en nuestro propio método.We can return a tuple from the parsing operation if we wrap the call to the Int32.TryParse method in our own method. En el ejemplo siguiente, NumericLibrary.ParseInteger llamadas la Int32.TryParse método y devuelve una tupla con nombre con dos elementos.In the following example, NumericLibrary.ParseInteger calls the Int32.TryParse method and returns a named tuple with two elements.

Imports System.Globalization

Public Module NumericLibrary
    Public Function ParseInteger(value As String) As (Success As Boolean, Number As Int32)
        Dim number As Integer
        Return (Int32.TryParse(value, NumberStyles.Any, CultureInfo.InvariantCulture, number), number)
    End Function
End Module

A continuación, puede llamar al método con código similar al siguiente:You can then call the method with code like the following:

Dim numericString As String = "123,456"
Dim result = ParseInteger(numericString)
Console.WriteLine($"{If(result.Success, $"Success: {result.Number:N0}", "Failure")}")
Console.ReadLine()
'      Output: Success: 123,456

Tuplas de Visual Basic y las tuplas en .NET FrameworkVisual Basic tuples and tuples in the .NET Framework

Una tupla de Visual Basic es una instancia de uno de los System.ValueTuple tipos genéricos, que se introdujeron en .NET Framework 4.7.A Visual Basic tuple is an instance of one of the System.ValueTuple generic types, which were introduced in the .NET Framework 4.7. .NET Framework también incluye un conjunto de genérico System.Tuple clases.The .NET Framework also includes a set of generic System.Tuple classes. Estas clases, pero difieren de las tuplas de Visual Basic y System.ValueTuple tipos genéricos en varios aspectos:These classes, however, differ from Visual Basic tuples and the System.ValueTuple generic types in a number of ways:

  • Los elementos de la tupla clases son propiedades denominadas Item1, Item2, y así sucesivamente.The elements of the Tuple classes are properties named Item1, Item2, and so on. En Visual Basic tuplas y ValueTuple tipos, elementos de tupla son campos.In Visual Basic tuples and the ValueTuple types, tuple elements are fields.

  • No se puede asignar nombres descriptivos a los elementos de un tupla instancia o de un ValueTuple instancia.You cannot assign meaningful names to the elements of a Tuple instance or of a ValueTuple instance. Visual Basic permite asignar nombres a los que se comunican el significado de los campos.Visual Basic allows you to assign names that communicate the meaning of the fields.

  • Las propiedades de un tupla instancia son de solo lectura; las tuplas son inmutables.The properties of a Tuple instance are read-only; the tuples are immutable. En Visual Basic tuplas y ValueTuple tipos, campos de tupla son de lectura y escritura; las tuplas son mutables.In Visual Basic tuples and the ValueTuple types, tuple fields are read-write; the tuples are mutable.

  • La interfaz genérica tupla tipos son tipos de referencia.The generic Tuple types are reference types. Uso de estos tupla implica la asignación de objetos de tipos.Using these Tuple types means allocating objects. En rutas de acceso activas, esto puede suponer un importante impacto en el rendimiento de la aplicación.On hot paths, this can have a measurable impact on your application's performance. Las tuplas de Visual Basic y ValueTuple tipos son tipos de valor.Visual Basic tuples and the ValueTuple types are value types.

Métodos de extensión en el TupleExtensions clase facilitan la conversión entre las tuplas de Visual Basic y .NET tupla objetos.Extension methods in the TupleExtensions class make it easy to convert between Visual Basic tuples and .NET Tuple objects. El ToTuple método convierte una tupla de Visual Basic en .NET tupla objeto y el ToValueTuple método convierte .NET tupla objeto en una tupla de Visual Basic.The ToTuple method converts a Visual Basic tuple to a .NET Tuple object, and the ToValueTuple method converts a .NET Tuple object to a Visual Basic tuple.

En el ejemplo siguiente se crea una tupla, lo convierte en un .NET tupla objeto y se convierte de nuevo a una tupla de Visual Basic.The following example creates a tuple, converts it to a .NET Tuple object, and converts it back to a Visual Basic tuple. El ejemplo, a continuación, comparan esta tupla con el original para asegurarse de que son iguales.The example then compares this tuple with the original one to ensure that they are equal.

Module Example
    Sub Main()
        Dim cityInfo = (name:="New York", area:=468.5, population:=8_550_405)
        Console.WriteLine($"{cityInfo}, type {cityInfo.GetType().Name}")

        ' Convert the Visual Basic tuple to a .NET tuple.
        Dim cityInfoT = TupleExtensions.ToTuple(cityInfo)
        Console.WriteLine($"{cityInfoT}, type {cityInfoT.GetType().Name}")

        ' Convert the .NET tuple back to a Visual Basic tuple and ensure they are the same.
        Dim cityInfo2 = TupleExtensions.ToValueTuple(cityInfoT)
        Console.WriteLine($"{cityInfo2}, type {cityInfo2.GetType().Name}")
        Console.WriteLine($"{NameOf(cityInfo)} = {NameOf(cityInfo2)}: {cityInfo.Equals(cityInfo2)}")
        Console.ReadLine()
    End Sub
End Module
' The example displays the following output:
'       (New York, 468.5, 8550405), type ValueTuple`3
'       (New York, 468.5, 8550405), type Tuple`3
'       (New York, 468.5, 8550405), type ValueTuple`3
'       cityInfo = cityInfo2 :  True

Vea tambiénSee also

Referencia del lenguaje Visual BasicVisual Basic Language Reference