Nota
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
En este artículo se enumeran los nombres de características clave para cada versión de Visual Basic, con descripciones detalladas de las características nuevas y mejoradas en las versiones más recientes del lenguaje.
Versión actual
Visual Basic 16.9 / Visual Studio 2019, versión 16.9
Para ver las nuevas características, consulte Visual Basic 16.9.
Puede descargar el SDK de .NET más reciente desde la página de descargas de .NET.
Versiones anteriores
Visual Basic 16.0 / Visual Studio 2019, versión 16.0
Para ver las nuevas características, consulte Visual Basic 16.0.
Visual Basic 15.5 / Visual Studio 2017, versión 15.5
Para ver las nuevas características, consulte Visual Basic 15.5.
Visual Basic 15.3 / Visual Studio 2017, versión 15.3
Para ver las nuevas características, consulte Visual Basic 15.3.
Visual Basic 15/Visual Studio 2017
Para ver las nuevas características, consulte Visual Basic 2017.
Visual Basic/Visual Studio 2015
Para ver las nuevas características, consulte Visual Basic 14.
Visual Basic/Visual Studio 2013
Versiones preliminares de tecnología de .NET Compiler Platform ("Roslyn")
Visual Basic/Visual Studio 2012
Async y await palabras clave, iteradores, atributos de información del autor de la llamada
Visual Basic, Visual Studio 2010
Propiedades implementadas automáticamente, inicializadores de colección, continuación de línea implícita, dinámica, varianza genérica de co/contra, acceso global al espacio de nombres
Visual Basic/Visual Studio 2008
Language Integrated Query (LINQ), literales XML, inferencia de tipos locales, inicializadores de objetos, tipos anónimos, métodos de extensión, inferencia de tipos locales var , expresiones lambda, if operador, métodos parciales, tipos de valor que aceptan valores NULL
Visual Basic/Visual Studio 2005
El My tipo y los tipos auxiliares (acceso a la aplicación, el equipo, el sistema de archivos, la red)
Visual Basic/Visual Studio .NET 2003
Operadores de desplazamiento de bits, declaración de variable de bucle
Visual Basic/Visual Studio .NET 2002
La primera versión de Visual Basic .NET
Visual Basic 16.9
Visual Basic 16.9 permite el consumo de propiedades solo iniciales.
Visual Basic 16.0
Visual Basic 16.0 se centra en proporcionar más características de Visual Basic Runtime (microsoft.visualbasic.dll) a .NET Core y es la primera versión de Visual Basic centrada en .NET Core. Las partes del runtime de Visual Basic que dependen de WinForms se agregaron en .NET Core 3.0.
Comentarios permitidos en más lugares dentro de instrucciones
En Visual Basic 15.5 y versiones anteriores, los comentarios solo se permiten en líneas en blanco, al final de una instrucción o en lugares específicos dentro de una instrucción donde se permite una continuación de línea implícita. A partir de Visual Basic 16.0, también se permiten comentarios después de las continuaciones explícitas de línea y dentro de una instrucción en una línea que comienza con un espacio seguido de un carácter de subrayado.
Public Sub Main()
cmd.CommandText = ' Comment is allowed here without _
"SELECT * FROM Titles JOIN Publishers " _ ' This is a comment
& "ON Publishers.PubId = Titles.PubID " _
_ ' This is a comment on a line without code
& "WHERE Publishers.State = 'CA'"
End Sub
Conversión optimizada de punto flotante a entero
En versiones anteriores de Visual Basic, la conversión de valores Double y Single a enteros ofrecía un rendimiento relativamente deficiente. Visual Basic 16.0 mejora significativamente el rendimiento de conversiones de punto flotante a enteros cuando se pasa el valor devuelto por cualquiera de los métodos siguientes a una de las funciones intrínsecas de conversión de enteros de Visual Basic (CByte, CShort, CInt, CLng, CSByte, CUShort, CUInt, CULng), o cuando el valor devuelto por cualquiera de los métodos siguientes se convierte implícitamente en un tipo entero cuando Option Strict se establece Offen :
- Conversion.Fix(Double)
- Conversion.Fix(Object)
- Conversion.Fix(Single)
- Conversion.Int(Double)
- Conversion.Int(Object)
- Conversion.Int(Single)
- Math.Ceiling(Double)
- Math.Floor(Double)
- Math.Round(Double)
- Math.Truncate(Double)
Esta optimización permite que el código se ejecute más rápido, hasta dos veces más rápido para el código que realiza un gran número de conversiones a tipos enteros. En el ejemplo siguiente se muestran algunas llamadas de método simples que se ven afectadas por esta optimización:
Dim s As Single = 173.7619
Dim d As Double = s
Dim i1 As Integer = CInt(Fix(s)) ' Result: 173
Dim b1 As Byte = CByte(Int(d)) ' Result: 173
Dim s1 AS Short = CShort(Math.Truncate(s)) ' Result: 173
Dim i2 As Integer = CInt(Math.Ceiling(d)) ' Result: 174
Dim i3 As Integer = CInt(Math.Round(s)) ' Result: 174
Tenga en cuenta que esto trunca en lugar de redondear valores de punto flotante.
Visual Basic 15.5
Argumentos con nombre no finales
En Visual Basic 15.3 y versiones anteriores, cuando una llamada al método incluía argumentos tanto por posición como por nombre, los argumentos posicionales tenían que preceder a los argumentos con nombre. A partir de Visual Basic 15.5, los argumentos posicionales y con nombre pueden aparecer en cualquier orden siempre que todos los argumentos hasta el último argumento posicional estén en la posición correcta. Esto resulta especialmente útil cuando se usan argumentos con nombre para que el código sea más legible.
Por ejemplo, la siguiente llamada al método tiene dos argumentos posicionales entre un argumento con nombre. El argumento con nombre deja claro que el valor 19 representa una edad.
StudentInfo.Display("Mary", age:=19, #9/21/1998#)
Private Protected modificador de acceso de miembro
Esta nueva combinación de palabras clave define un miembro al que pueden acceder todos los miembros de su clase contenedora, así como por tipos derivados de la clase contenedora, pero solo si también se encuentran en el ensamblado contenedor. Dado que las estructuras no se pueden heredar, Private Protected solo se pueden aplicar a los miembros de una clase.
Separador hexadecimal/ binario/octal inicial
Visual Basic 2017 agregó compatibilidad con el carácter de subrayado (_) como separador de dígitos. 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 o octales. En el ejemplo siguiente se usa un separador de dígitos inicial para definir 3.271.948.384 como un número hexadecimal:
Dim number As Integer = &H_C305_F860
Para usar el carácter de subrayado como separador inicial, debe agregar el siguiente elemento al archivo del proyecto de Visual Basic (*.vbproj):
<PropertyGroup>
<LangVersion>15.5</LangVersion>
</PropertyGroup>
Visual Basic 15.3
Inferencia de tupla con nombre
Al asignar el valor de los elementos de tupla de variables, Visual Basic deduce el nombre de los elementos de tupla a partir de los nombres de variable correspondientes; no es necesario asignar un nombre explícito a un elemento de tupla. En el ejemplo siguiente se usa la inferencia para crear una tupla con tres elementos con nombre, state, stateNamey capital.
Const state As String = "MI"
Const stateName As String = "Michigan"
Const capital As String = "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 de compilador adicionales
El compilador de línea de comandos de Visual Basic ahora admite las opciones del compilador -refout y -refonly para controlar la salida de los ensamblados de referencia. -refout define el directorio de salida del ensamblado de referencia y -refonly especifica que solo se va a generar un ensamblado de referencia mediante la compilación.
Visual Basic 15
Las tuplas son una estructura de datos ligera que normalmente se usa para devolver varios valores desde una sola llamada de método. Normalmente, para devolver varios valores de un método, debe realizar una de las acciones siguientes:
Defina un tipo personalizado (o
Class).StructureSe trata de una solución de peso pesado.Defina uno o varios
ByRefparámetros, además de devolver un valor del método .
La compatibilidad de Visual Basic con tuplas le permite definir rápidamente una tupla, asignar opcionalmente nombres semánticos a sus valores y recuperar rápidamente sus valores. En el ejemplo siguiente se ajusta una llamada al TryParse método y se devuelve una tupla.
Imports System.Globalization
Public Module NumericLibrary
Public Function ParseInteger(value As String) As (Success As Boolean, Number As Integer)
Dim number As Integer
Return (Integer.TryParse(value, NumberStyles.Any, CultureInfo.InvariantCulture, number), number)
End Function
End Module
A continuación, puede llamar al método y controlar la tupla devuelta con código como el siguiente.
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ígitos
Puede definir un literal binario mediante el prefijo &B o &b. Además, puede usar el carácter de subrayado, _, como separador de dígitos para mejorar la legibilidad. En el ejemplo siguiente se usan ambas características para asignar un Byte valor y mostrarlo como un número decimal, hexadecimal y binario.
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 .
Compatibilidad con valores devueltos de referencia de C#
C# admite valores devueltos de referencia. Es decir, cuando el método de llamada recibe un valor devuelto por referencia, puede cambiar el valor de la referencia. Visual Basic no permite crear métodos con valores devueltos de referencia, pero permite consumir y modificar los valores devueltos de referencia.
Por ejemplo, la siguiente Sentence clase escrita en C# incluye un FindNext método que encuentra la siguiente palabra en una oración que comienza con una subcadena especificada. La cadena se devuelve como un valor devuelto de referencia y una Boolean variable pasada por referencia al método indica si la búsqueda se realizó correctamente. Esto significa que, además de leer el valor devuelto, el autor de la llamada también puede modificarlo y esa modificación se refleja en la Sentence clase .
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 encuentra en la oración mediante código como el siguiente. 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.
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.
Sin embargo, un problema con este código es que, si no se encuentra una coincidencia, el método devuelve la primera palabra. Dado que el ejemplo no examina el valor del Boolean argumento para determinar si se encuentra una coincidencia, modifica la primera palabra si no hay ninguna coincidencia. En el ejemplo siguiente se corrige esto reemplazando la primera palabra por sí misma si no hay ninguna coincidencia.
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 mejor solución consiste en usar un método auxiliar al que se pasa el valor devuelto de referencia por referencia. A continuación, el método auxiliar puede modificar el argumento que se le pasa por referencia. En el ejemplo siguiente se hace eso.
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.
Visual Basic 14
Puede obtener el nombre de cadena no calificado de un tipo o miembro para usarlo en un mensaje de error sin codificar una cadena de forma rígida. Esto permite que el código permanezca correcto al refactorizar. Esta característica también es útil para enlazar vínculos MVC del controlador de vista del modelo y desencadenar eventos modificados de propiedades.
Puede usar expresiones de interpolación de cadenas para construir cadenas. Una expresión de cadena interpolada es similar a una cadena de plantilla que contiene expresiones. Una cadena interpolada es más fácil de entender con respecto a los argumentos que el formato compuesto.
Acceso y indexación de miembros condicionales NULL
Puede probar null de una manera sintáctica muy ligera antes de realizar una operación de acceso a miembros (?.) o índice (?[]). Estos operadores le ayudan a escribir menos código para controlar comprobaciones nulas, especialmente para descendentes en estructuras de datos. Si el operando izquierdo o la referencia de objeto es NULL, las operaciones devuelven null.
Literales de cadena de varias líneas
Los literales de cadena pueden contener secuencias de nueva línea. Ya no necesita el antiguo trabajo de uso <xml><![CDATA[...text with newlines...]]></xml>.Value
Comentarios
Puede colocar comentarios después de las continuaciones de línea implícitas, dentro de las expresiones del inicializador y entre los términos de expresión LINQ.
Resolución de nombres completa más inteligente
Dado código como Threading.Thread.Sleep(1000), Visual Basic se usó para buscar el espacio de nombres "Threading", detectar que era ambiguo entre System.Threading y System.Windows.Threading y, a continuación, notificar un error. Visual Basic ahora considera ambos posibles espacios de nombres juntos. Si muestra la lista de finalización, el editor de Visual Studio enumera los miembros de ambos tipos en la lista de finalización.
Literales de fecha de año
Puede tener literales de fecha en formato aaaa-mm-dd, #2015-03-17 16:10 PM#.
Propiedades de la interfaz readonly
Puede implementar propiedades de interfaz readonly mediante una propiedad readwrite. La interfaz garantiza la funcionalidad mínima y no impide que se establezca una clase de implementación.
Para obtener más legibilidad del código, ahora puede usar TypeOf con IsNot.
id.> de advertencia <de #Disable y id. de advertencia <de #Enable>
Puede deshabilitar y habilitar advertencias específicas para regiones dentro de un archivo de origen.
Mejoras en los comentarios de documentos XML
Al escribir comentarios de documentos, obtendrá compatibilidad con el editor inteligente y la compilación para validar los nombres de parámetros, el control adecuado de crefs (genéricos, operadores, etc.), el coloreado y la refactorización.
Definiciones parciales de módulo e interfaz
Además de las clases y estructuras, puede declarar módulos e interfaces parciales.
#Region directivas dentro de los cuerpos del método
Puede colocar #Region...#End delimitadores de región en cualquier lugar de un archivo, dentro de funciones e incluso abarcar entre cuerpos de función.
Las definiciones de invalidaciones son sobrecargas implícitas
Si agrega el Overrides modificador a una definición, el compilador agrega Overloads implícitamente para que pueda escribir menos código en casos comunes.
CObj permitido en los argumentos de atributos
El compilador usado para dar un error que CObj(...) no era una constante cuando se usaba en construcciones de atributos.
Declarar y consumir métodos ambiguos de diferentes interfaces
Anteriormente, el código siguiente generaba errores que le impedían declarar IMock o llamar a GetDetails (si se habían declarado en 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 usará reglas de resolución de sobrecarga normales para elegir el más adecuado GetDetails para llamar a y puede declarar relaciones de interfaz en Visual Basic como las que se muestran en el ejemplo.