Novedades de Visual BasicWhat's new for Visual Basic

En este tema se enumeran los nombres de las características clave de cada versión de Visual Basic con descripciones detalladas de las características nuevas y mejoradas de las versiones más recientes del lenguaje.This topic lists key feature names for each version of Visual Basic, with detailed descriptions of the new and enhanced features in the latest versions of the language.

Versión actualCurrent version

Visual Basic 15.5 / Visual Studio 2017 versión 15.5Visual Basic 15.5 / Visual Studio 2017 Version 15.5
Para ver las características nuevas, vea Visual Basic 15.5For new features, see Visual Basic 15.5

Versiones anterioresPrevious versions

Visual Basic 15.3 / Visual Studio 2017, versión 15.3Visual Basic 15.3 / Visual Studio 2017 Version 15.3
Para ver las características nuevas, vea Visual Basic 15.3For new features, see Visual Basic 15.3

Visual Basic 2017 / Visual Studio 2017Visual Basic 2017 / Visual Studio 2017
Para obtener características nuevas, vea Visual Basic 2017.For new features, see Visual Basic 2017

Visual Basic / Visual Studio 2015Visual Basic / Visual Studio 2015
Para obtener características nuevas, vea Visual Basic 14.For new features, see Visual Basic 14

Visual Basic / Visual Studio 2013Visual Basic / Visual Studio 2013
Vistas previas de tecnología de .NET Compiler Platform ("Roslyn")Technology previews of the .NET Compiler Platform (“Roslyn”)

Visual Basic / Visual Studio 2012Visual Basic / Visual Studio 2012
palabras clave Async y await, iteradores, atributos de información de autor de llamadaAsync and await keywords, iterators, caller info attributes

Visual Basic, Visual Studio 2010Visual Basic, Visual Studio 2010
Propiedades autoimplementadas, inicializadores de colección, continuación de línea implícita, dinámica, covarianza/contravarianza genérica, acceso de espacio de nombres globalAuto-implemented properties, collection initializers, implicit line continuation, dynamic, generic co/contra variance, global namespace access

Visual Basic / Visual Studio 2008Visual Basic / Visual Studio 2008
Language Integrated Query (LINQ), literales XML, inferencia de tipo de variable local, inicializadores de objeto, tipos anónimos, métodos de extensión, inferencia de tipo de variable local var, expresiones lambda, operador if, métodos parciales, tipos de valor que aceptan valores nullLanguage Integrated Query (LINQ), XML literals, local type inference, object initializers, anonymous types, extension methods, local var type inference, lambda expressions, if operator, partial methods, nullable value types

Visual Basic / Visual Studio 2005Visual Basic / Visual Studio 2005
El tipo My y los tipos del asistente (acceso a la aplicación, equipo, sistema de archivos, red)The My type and helper types (access to app, computer, files system, network)

Visual Basic / Visual Studio .NET 2003Visual Basic / Visual Studio .NET 2003
Operadores de desplazamiento de bits, declaración de variable de bucleBit-shift operators, loop variable declaration

Visual Basic / Visual Studio .NET 2002Visual Basic / Visual Studio .NET 2002
La primera versión de Visual Basic .NETThe first release of Visual Basic .NET

Visual Basic 15.5Visual Basic 15.5

Argumentos con nombre no finalesNon-trailing named arguments

En Visual Basic 15.3 y en versiones anteriores, cuando una llamada de método incluía argumentos por posición y por nombre, los argumentos posicionales tenían que preceder a los argumentos con nombre.In Visual Basic 15.3 and earlier versions, when a method call included arguments both by position and by name, positional arguments had to precede named arguments. A partir de Visual Basic 15.5, los argumentos posicionales y los argumentos con nombre pueden aparecer en cualquier orden, siempre y cuando todos los argumentos hasta el último argumento posicional se encuentren en la posición correcta.Starting with Visual Basic 15.5, positional and named arguments can appear in any order as long as all arguments up to the last positional argument are in the correct position. Esto es muy útil si se usan argumentos con nombre para mejorar la legibilidad del código.This is particularly useful when named arguments are used to make code more readable.

Por ejemplo, la siguiente llamada de método tiene dos argumentos posicionales entre un argumento con nombre.For example, the following method call has two positional arguments between a named argument. El argumento con nombre deja claro que el valor 19 representa una edad.The named argument makes it clear that the value 19 represents an age.

StudentInfo.Display("Mary", age:=19, #9/21/1998#)

Modificador de acceso de miembro Private ProtectedPrivate Protected member access modifier

Esta nueva combinación de palabras clave define un miembro al que pueden acceder todos los miembros de su clase contenedora y los tipos derivados de dicha clase, pero solo si también se encuentran en el ensamblado contenedor.This new keyword combination defines a member that is accessible by all members in its containing class as well as by types derived from the containing class, but only if they are also found in the containing assembly. Dado que las estructuras no se pueden heredar, Private Protected solo se pueden aplicar a los miembros de una clase.Because structures cannot be inherited, Private Protected can only be applied to the members of a class.

Separador hexadecimal/binario/octal inicialLeading hex/binary/octal separator

En Visual Basic 2017 se ha agregado compatibilidad con el carácter de subrayado (_) como separador de dígitos.Visual Basic 2017 added support for the underscore character (_) as a digit separator. A partir de Visual Basic 15.5 puede usar el carácter de subrayado como separador inicial entre el prefijo y los dígitos hexadecimales, binarios u octales.Starting with Visual Basic 15.5, you can use the underscore character as a leading separator between the prefix and hexadecimal, binary, or octal digits. En el ejemplo siguiente se usa un separador de dígitos inicial para definir 3,271,948,384 como número hexadecimal:The following example uses a leading digit separator to define 3,271,948,384 as a hexadecimal number:

Dim number As Integer = &H_C305_F860

Para usar el carácter de subrayado como separador inicial, debe agregar el elemento siguiente al archivo del proyecto de Visual Basic (*.vbproj):To use the underscore character as a leading separator, you must add the following element to your Visual Basic project (*.vbproj) file:

<PropertyGroup>
  <LangVersion>15.5</LangVersion>
</PropertyGroup>

Visual Basic 15.3Visual Basic 15.3

Inferencia en tuplas con nombreNamed tuple inference

Al asignar el valor de elementos de tupla desde variables, Visual Basic infiere el nombre de los elementos de tupla a partir de los nombres de variable correspondientes, por lo que no es necesario asignar un nombre a un elemento de tupla de forma explícita.When you assign the value of tuple elements from variables, Visual Basic infers the name of tuple elements from the corresponding variable names; you do not have to explicitly name a tuple element. En el ejemplo siguiente se usa la inferencia para crear una tupla con tres elementos con nombre: state, stateName y capital.The following example uses inference to create a tuple with three named elements, state, stateName, and capital.

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

Modificadores del compilador adicionalesAdditional compiler switches

El compilador de línea de comandos de Visual Basic ahora admite las opciones de compilador -refout y -refonly para controlar la salida de ensamblados de referencia.The Visual Basic command-line compiler now supports the -refout and -refonly compiler options to control the output of reference assemblies. -refout define el directorio de salida del ensamblado de referencia y -refonly especifica que solo un ensamblado de referencia se transferirá por compilación.-refout defines the output directory of the reference assembly, and -refonly specifies that only a reference assembly is to be output by compilation.

Visual Basic 2017Visual Basic 2017

TuplasTuples

Las tuplas son una estructura de datos ligera que se usan normalmente para devolver varios valores de una sola llamada al método.Tuples are a lightweight data structure that most commonly is used to return multiple values from a single method call. Normalmente, para devolver varios valores de un método, tiene que realizar una de las siguientes acciones:Ordinarily, to return multiple values from a method, you have to do one of the following:

  • Definir un tipo personalizado (Class o Structure).Define a custom type (a Class or a Structure). Esta es una solución pesada.This is a heavyweight solution.

  • Definir uno o más parámetros ByRef, además de devolver un valor del método.Define one or more ByRef parameters, in addition to returning a value from the method.

La compatibilidad de Visual Basic con las tuplas le permite definir rápidamente una tupla, asignar opcionalmente nombres semánticos a sus valores y recuperar sus valores rápidamente.Visual Basic's support for tuples lets you quickly define a tuple, optionally assign semantic names to its values, and quickly retrieve its values. En el ejemplo siguiente se ajusta una llamada al método TryParse y se devuelve una tupla.The following example wraps a call to the TryParse method and returns a tuple.

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

Después, puede llamar al método y controlar la tupla devuelta con código como el siguiente.You can then call the method and handle the returned tuple 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

Literales binarios y separadores de dígitosBinary literals and digit separators

Puede definir un literal binario con el prefijo &B o &b.You can define a binary literal by using the prefix &B or &b. Además, puede usar el carácter de subrayado, _, como un separador de dígitos para mejorar la legibilidad.In addition, you can use the underscore character, _, as a digit separator to enhance readability. En el ejemplo siguiente se usan ambas características para asignar un valor Byte y para mostrarlo como un número binario, hexadecimal y decimal.The following example uses both features to assign a Byte value and to display it as a decimal, hexadecimal, and binary number.

Dim value As Byte = &B0110_1110
Console.WriteLine($"{NameOf(value)}  = {value} (hex: 0x{value:X2}) " +
                  $"(binary: {Convert.ToString(value, 2)})")
' The example displays the following output:
'      value  = 110 (hex: 0x6E) (binary: 1101110)      

Para obtener más información, vea la sección "Asignaciones literales" de los tipos de datos Byte, Integer, Long, Short, SByte, UInteger, ULong y UShort.For more information, see the "Literal assignments" section of the Byte, Integer, Long, Short, SByte, UInteger, ULong, and UShort data types.

Compatibilidad con los valores devueltos de referencia de C#Support for C# reference return values

A partir de C# 7.0, C# admite los valores devueltos de referencia.Starting with C# 7.0, C# supports reference return values. Es decir, cuando el método de llamada recibe un valor devuelto mediante referencia, puede cambiar el valor de esta.That is, when the calling method receives a value returned by reference, it can change the value of the reference. Visual Basic no le permite crear métodos con valores devueltos de referencia, pero le permite consumirlos y modificarlos.Visual Basic does not allow you to author methods with reference return values, but it does allow you to consume and modify the reference return values.

Por ejemplo, la siguiente clase Sentence escrita en C# incluye un método FindNext que busca la siguiente palabra de una frase que comienza por una subcadena especificada.For example, the following Sentence class written in C# includes a FindNext method that finds the next word in a sentence that begins with a specified substring. La cadena se devuelve como un valor devuelto de referencia, y una variable Boolean que se ha pasado mediante referencia al método indica si la búsqueda se ha realizado correctamente.The string is returned as a reference return value, and a Boolean variable passed by reference to the method indicates whether the search was successful. Esto significa que el autor de la llamada no solo puede leer el valor devuelto; él o ella también puede modificarlo, y esa modificación se refleja en la clase Sentence.This means that the caller can not only read the returned value; he or she can also modify it, and that modification is reflected in the Sentence class.

using System;
 
public class Sentence
{
    private string[] words;
    private int currentSearchPointer;
    
    public Sentence(string sentence)
    {
        words = sentence.Split(' ');
        currentSearchPointer = -1;
    }
    
    public ref string FindNext(string startWithString, ref bool found)
    {
        for (int count = currentSearchPointer + 1; count < words.Length; count++)
        {
            if (words[count].StartsWith(startWithString))
            {
                currentSearchPointer = count;
                found = true;
                return ref words[currentSearchPointer];
            }
        }
        currentSearchPointer = -1;
        found = false;
        return ref words[0];
    }
    
    public string GetSentence()
    {
        string stringToReturn = null;
        foreach (var word in words)
            stringToReturn += $"{word} ";
      
        return stringToReturn.Trim();    
    }
}

En su forma más sencilla, puede modificar la palabra que se ha encontrado en la frase con código como el que se muestra a continuación.In its simplest form, you can modify the word found in the sentence by using code like the following. Tenga en cuenta que no está asignando un valor al método, sino a la expresión que devuelve el método, que es el valor devuelto de referencia.Note that you are not assigning a value to the method, but rather to the expression that the method returns, which is the reference return value.

Dim sentence As New Sentence("A time to see the world is now.")
Dim found = False
sentence.FindNext("A", found) = "A good" 
Console.WriteLine(sentence.GetSentence()) 
' The example displays the following output:
'      A good time to see the world is now.

En cambio, un problema con este código es que si no se detecta una coincidencia, el método devuelve la primera palabra.A problem with this code, though, is that if a match is not found, the method returns the first word. Como el ejemplo no examina el valor del argumento Boolean para determinar si se detecta una coincidencia, modifica la primera palabra si no hay ninguna.Since the example does not examine the value of the Boolean argument to determine whether a match is found, it modifies the first word if there is no match. En el ejemplo siguiente se corrige esto reemplazando la primera palabra por ella misma si no existe ninguna coincidencia.The following example corrects this by replacing the first word with itself if there is no match.

Dim sentence As New Sentence("A time to see the world is now.")
Dim found = False
sentence.FindNext("A", found) = IIf(found, "A good", sentence.FindNext("B", found)) 
Console.WriteLine(sentence.GetSentence()) 
' The example displays the following output:
'      A good time to see the world is now.

Una solución mejor es usar un método del asistente en el que el valor devuelto de referencia se pase mediante una referencia.A better solution is to use a helper method to which the reference return value is passed by reference. El método del asistente puede después modificar el argumento que se ha pasado por referencia.The helper method can then modify the argument passed to it by reference. En el siguiente ejemplo se realiza esto.The following example does that.

Module Example
   Public Sub Main()
      Dim sentence As New Sentence("A time to see the world is now.")
      Dim found = False
      Dim returns = RefHelper(sentence.FindNext("A", found), "A good", found) 
      Console.WriteLine(sentence.GetSentence()) 
   End Sub
   
   Private Function RefHelper(ByRef stringFound As String, replacement As String, success As Boolean) _ 
                    As (originalString As String, found As Boolean) 
      Dim originalString = stringFound
      If found Then stringFound = replacement
      Return (originalString, found)   
   End Function
End Module
' The example displays the following output:
'      A good time to see the world is now.

Para obtener más información, vea Valores devueltos de referencia.For more information, see Reference Return Values.

Visual Basic 14Visual Basic 14

NameofNameof
Puede obtener el nombre de cadena no calificado de un tipo o miembro para usarlo en un mensaje de error sin codificar de forma rígida una cadena.You can get the unqualified string name of a type or member for use in an error message without hard coding a string. Esto permite que el código siga siendo correcto al refactorizarlo.This allows your code to remain correct when refactoring. Esta característica también es útil para enlazar los vínculos MVC del controlador de vista de modelos y desencadenar eventos de propiedad cambiada.This feature is also useful for hooking up model-view-controller MVC links and firing property changed events.

Interpolación de cadenasString interpolation
Puede usar expresiones de interpolación de cadenas para construir cadenas.You can use string interpolation expressions to construct strings. Una expresión de cadena interpolada es similar a una cadena de plantilla que contiene expresiones.An interpolated string expression looks like a template string that contains expressions. Una cadena interpolada es más fácil de entender con respecto a los argumentos que el formato compuesto.An interpolated string is easier to understand with respect to arguments than Composite Formatting.

Acceso a miembros condicionales NULL e indexaciónNull-conditional member access and indexing
Puede probar si hay valores null de forma sintáctica ligera antes de realizar una operación de acceso a miembros (?.) o índice (?[]).You can test for null in a very light syntactic way before performing a member access (?.) or index (?[]) operation. Estos operadores ayudan a escribir menos código para controlar las comprobaciones de null, especialmente para descender en estructuras de datos.These operators help you write less code to handle null checks, especially for descending into data structures. Si la referencia de objeto u operando izquierdo es null, la operación devuelve null.If the left operand or object reference is null, the operations returns null.

Literales de cadena multilíneaMulti-line string literals
Los literales de cadena pueden contener secuencias de nueva línea.String literals can contain newline sequences. Ya no necesita la antigua solución alternativa que consistía en usar <xml><![CDATA[...text with newlines...]]></xml>.ValueYou no longer need the old work around of using <xml><![CDATA[...text with newlines...]]></xml>.Value

ComentariosComments
Puede colocar comentarios después de las continuaciones de línea implícita, dentro de expresiones de inicializador y entre los términos de la expresión LINQ.You can put comments after implicit line continuations, inside initializer expressions, and among LINQ expression terms.

Resolución de nombres completos más inteligenteSmarter fully-qualified name resolution
Dado código como Threading.Thread.Sleep(1000), Visual Basic solía buscar el espacio de nombres "Threading", detectaba ambigüedad entre System.Threading y System.Windows.Threading y, a continuación, notificaba un error.Given code such as Threading.Thread.Sleep(1000), Visual Basic used to look up the namespace "Threading", discover it was ambiguous between System.Threading and System.Windows.Threading, and then report an error. Ahora, Visual Basic considera juntos ambos espacios de nombres posibles.Visual Basic now considers both possible namespaces together. Si aparece la lista de finalización, el editor de Visual Studio muestra los miembros de ambos tipos en la lista de finalización.If you show the completion list, the Visual Studio editor lists members from both types in the completion list.

Literales de fecha con el año en primer lugarYear-first date literals
Puede tener literales de fecha en el formato aaaa-mm-dd, #2015-03-17 16:10 PM#.You can have date literals in yyyy-mm-dd format, #2015-03-17 16:10 PM#.

Propiedades de interfaz de solo lecturaReadonly interface properties
Puede implementar propiedades de interfaz de solo lectura mediante una propiedad de lectura y escritura.You can implement readonly interface properties using a readwrite property. La interfaz garantiza una funcionalidad mínima y no impide que una clase de implementación pueda establecer la propiedad.The interface guarantees minimum functionality, and it does not stop an implementing class from allowing the property to be set.

TypeOf <expr> IsNot <type>TypeOf <expr> IsNot <type>
Para mejorar la legibilidad del código, ahora puede usar TypeOf con IsNot.For more readability of your code, you can now use TypeOf with IsNot.

#Disable Warning <ID> y #Enable Warning <ID>#Disable Warning <ID> and #Enable Warning <ID>
Puede deshabilitar y habilitar advertencias específicas para las regiones dentro de un archivo de origen.You can disable and enable specific warnings for regions within a source file.

Mejoras de comentarios de documento XMLXML doc comment improvements
Al escribir comentarios de documento, obtiene compatibilidad inteligente de editor y compilación para validar nombres de parámetro, controlar adecuadamente crefs (genéricos, operadores, etc.), colorear y refactorizar.When writing doc comments, you get smart editor and build support for validating parameter names, proper handling of crefs (generics, operators, etc.), colorizing, and refactoring.

Definiciones de módulo parcial e interfazPartial module and interface definitions
Además de clases y structs, puede declarar módulos parciales e interfaces.In addition to classes and structs, you can declare partial modules and interfaces.

Directivas #Region dentro de cuerpos de método#Region directives inside method bodies
Puede colocar delimitadores #Region... #End Region en cualquier parte de un archivo, dentro de funciones e incluso abarcando los cuerpos de función.You can put #Region…#End Region delimiters anywhere in a file, inside functions, and even spanning across function bodies.

Las definiciones de invalidaciones son implícitamente sobrecargasOverrides definitions are implicitly overloads
Si agrega el modificador Overrides a una definición, el compilador agrega implícitamente Overloads, de modo que pueda escribir menos código en los casos comunes.If you add the Overrides modifier to a definition, the compiler implicitly adds Overloads so that you can type less code in common cases.

CObj permitido en argumentos de atributosCObj allowed in attributes arguments
El compilador solía producir un error advirtiendo de que CObj(...) no era una constante cuando se usaba en construcciones de atributo.The compiler used to give an error that CObj(…) was not a constant when used in attribute constructions.

Declaración y consumo de métodos ambiguos desde otras interfacesDeclaring and consuming ambiguous methods from different interfaces
Anteriormente, en el código siguiente producía errores que impedían declarar IMock o llamar a GetDetails (si estos se habían declarado en C#):Previously the following code yielded errors that prevented you from declaring IMock or from calling GetDetails (if these had been declared in C#):

Interface ICustomer  
  Sub GetDetails(x As Integer)  
End Interface  
  
Interface ITime  
  Sub GetDetails(x As String)  
End Interface  
  
Interface IMock : Inherits ICustomer, ITime  
  Overloads Sub GetDetails(x As Char)  
End Interface  
  
Interface IMock2 : Inherits ICustomer, ITime  
End Interface  

Ahora el compilador usa las reglas de resolución de sobrecarga normales para elegir el GetDetails más apropiado que se va a llamar, y se pueden declarar relaciones de interfaz en Visual Basic como las que se muestran en el ejemplo.Now the compiler will use normal overload resolution rules to choose the most appropriate GetDetails to call, and you can declare interface relationships in Visual Basic like those shown in the sample.

Vea tambiénSee also

Novedades de Visual Studio 2017What's New in Visual Studio 2017