O que há de novo para Visual Basic
Este tópico lista nomes-chave para cada versão de Visual Basic, com descrições detalhadas das novas funcionalidades e melhoradas nas versões mais recentes do idioma.
Versão atual
Visual Basic 16.9 / Visual Studio versão 2019 16.9
Para novas funcionalidades, consulte Visual Basic 16.9.
Pode baixar as últimas informações .NET SDK a partir da página de downloads .NET.
Versões anteriores
Visual Basic 16.0 / Visual Studio versão 2019 16.0
Para novas funcionalidades, consulte Visual Basic 16.0.
Visual Basic 15.5 / Visual Studio versão 2017 15.5
Para obter novas funcionalidades, consulte Visual Basic 15.5.
Visual Basic 15.3 / Visual Studio versão 2017 15.3
Para obter novas funcionalidades, consulte Visual Basic 15.3.
Visual Basic 15 / Visual Studio 2017
Para novas funcionalidades, consulte Visual Basic 2017.
Visual Basic / Visual Studio 2015
Para novas funcionalidades, consulte Visual Basic 14.
Visual Basic / Visual Studio 2013
Pré-visualizações tecnológicas da Plataforma compilador .NET ("Roslyn")
Visual Basic / Visual Studio 2012
Async
e await
palavras-chave, iteradores, atributos de informação de chamada
Visual Basic, Visual Studio 2010
Propriedades auto-implementadas, inicializadores de recolha, continuação implícita da linha, dinâmica, co/contra variância genérica, acesso global ao espaço de nome
Visual Basic / Visual Studio 2008
Consulta Integrada de Linguagem (LINQ), literais XML, inferência de tipo local, inicializadores de objetos, tipos anónimos, métodos de extensão, inferência de tipo local var
, expressões de lambda, if
operador, métodos parciais, tipos de valor anulados
Visual Basic / Visual Studio 2005
Os My
tipos de tipo e ajudante (acesso a app, computador, sistema de ficheiros, rede)
Visual Basic / Visual Studio .NET 2003
Operadores de mudança de bit, declaração variável de loop
Visual Basic / Visual Studio .NET 2002
O primeiro lançamento de Visual Basic .NET
Visual Basic 16.9
Visual Basic 16.9 permite o consumo de propriedades init-only.
Visual Basic 16.0
Visual Basic 16.0 foca-se em fornecer mais das funcionalidades do Visual Basic Runtime (microsoft.visualbasic.dll) a .NET Core e é a primeira versão de Visual Basic focada em .NET Core. Muitas partes do Visual Basic Runtime dependem do WinForms e estas serão adicionadas numa versão posterior de Visual Basic.
Comentários permitidos em mais lugares dentro de declarações
Em Visual Basic versões 15.8 e anteriores, os comentários são apenas permitidos em linhas em branco, no final de uma declaração, ou em locais específicos dentro de uma declaração onde é permitida a continuação de uma linha implícita. Começando com Visual Basic 16.0, os comentários também são permitidos após continuações explícitas da linha e dentro de uma declaração sobre uma linha que começa com um espaço seguido de um sublinhado.
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
Ponto flutuante otimizado para conversão de inteiros
Em versões anteriores de Visual Basic, a conversão de valores duplos e únicos para inteiros oferecia um desempenho relativamente fraco. Visual Basic 15.8 melhora significativamente o desempenho das conversões de pontos flutuantes para os inteiros quando se transmite o valor devolvido por qualquer um dos seguintes métodos para uma das funções de conversão Visual Basic inteiros intrínsecas (CByte, CByte, CShort, CInt, CLng, CSByte, CUShort, CUInt, CULng), ou quando o valor devolvido por qualquer um dos seguintes métodos é implicitamente moldado para um tipo integral quando A opção Estrita está definida paraOff
:
- 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 otimização permite que o código seja executado mais rapidamente -- até o dobro do rápido para código que faz um grande número de conversões para tipos inteiros. O exemplo a seguir ilustra algumas chamadas simples de método que são afetadas por esta otimização:
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
Note que isto trunca em vez de roda valores de ponto flutuante.
Visual Basic 15.5
Em Visual Basic versões 15.3 e anteriores, quando uma chamada de método incluía argumentos tanto por posição como por nome, os argumentos posicionais tinham de preceder os argumentos nomeados. Começando com Visual Basic 15.5, os argumentos posicionais e nomeados podem aparecer em qualquer ordem, desde que todos os argumentos até ao último argumento posicional estejam na posição correta. Isto é particularmente útil quando os argumentos nomeados são usados para tornar o código mais legível.
Por exemplo, a chamada de método a seguir tem dois argumentos posicionais entre um argumento nomeado. O argumento nomeado deixa claro que o valor 19 representa uma idade.
StudentInfo.Display("Mary", age:=19, #9/21/1998#)
Private Protected
modificador de acesso ao membro
Esta nova combinação de palavras-chave define um membro acessível por todos os membros da sua classe contendo, bem como por tipos derivados da classe contendo, mas apenas se forem encontrados na montagem contendo. Como as estruturas não podem ser herdadas, Private Protected
só podem ser aplicadas aos membros de uma classe.
Separador líder do hexa/binário/octal
Visual Basic 2017 acrescentou suporte para o caráter de sublinhado (_
) como separador de dígitos. Começando com Visual Basic 15.5, pode usar o personagem de sublinhado como separador principal entre os dígitos prefixo e hexadémico, binário ou octal. O exemplo a seguir utiliza um separador de dígitos líder para definir 3.271.948.384 como um número hexadecimal:
Dim number As Integer = &H_C305_F860
Para utilizar o carácter de sublinhado como separador principal, deve adicionar o seguinte elemento ao seu ficheiro Visual Basic projeto (*.vbproj):
<PropertyGroup>
<LangVersion>15.5</LangVersion>
</PropertyGroup>
Visual Basic 15.3
Quando atribui o valor dos elementos tuple a partir de variáveis, Visual Basic inferi o nome dos elementos tuple dos nomes variáveis correspondentes; não tem de nomear explicitamente um elemento de tuple. O exemplo a seguir usa inferência para criar um tuple com três elementos nomeados, state
e capital
stateName
.
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
Interruptores de compilador adicionais
O compilador de linha de comando Visual Basic suporta agora as opções de compilador -reout e -refonly para controlar a saída dos conjuntos de referência. O re-escout define o diretório de saída do conjunto de referência, e -refonly especifica que apenas um conjunto de referência deve ser de saída por compilação.
Visual Basic 15
Tuples é uma estrutura de dados leve que mais frequentemente é usada para devolver vários valores de uma única chamada de método. Normalmente, para devolver vários valores de um método, tem de fazer um dos seguintes:
Defina um tipo personalizado (a
Class
ou aStructure
). Esta é uma solução de pesos pesados.Defina um ou mais
ByRef
parâmetros, além de devolver um valor do método.
O apoio da Visual Basic aos tuples permite-lhe definir rapidamente um tuple, atribuindo opcionalmente nomes semânticos aos seus valores, e rapidamente recuperar os seus valores. O exemplo a seguir envolve uma chamada ao TryParse método e devolve uma tuple.
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
Em seguida, pode ligar para o método e manusear a tuple devolvida com código como o seguinte.
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 binárias e separadores de dígitos
Pode definir um literal binário utilizando o prefixo &B
ou &b
. Além disso, pode usar o caráter de sublinhado, _
como separador de dígitos para aumentar a legibilidade. O exemplo a seguir utiliza ambas as funcionalidades para atribuir um Byte
valor e exibi-lo como um número decimal, hexadecimal e binário.
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 mais informações, consulte a secção "Atribuições Literais" dos tipos de dados Byte, Inte, Long, Short, SByte, UInteger, ULong e UShort .
Suporte para valores de retorno de referência C#
Começando por C# 7.0, C# suporta valores de retorno de referência. Ou seja, quando o método de chamada recebe um valor devolvido por referência, pode alterar o valor da referência. Visual Basic não lhe permite autoriar métodos com valores de retorno de referência, mas permite-lhe consumir e modificar os valores de retorno de referência.
Por exemplo, a seguinte Sentence
classe escrita em C# inclui um FindNext
método que encontra a próxima palavra numa frase que começa com um sub-adcção especificado. A cadeia é devolvida como um valor de retorno de referência, e uma Boolean
variável passada por referência ao método indica se a pesquisa foi bem sucedida. Isto significa que, além de ler o valor devolvido, o chamador também pode modificá-lo, e essa modificação reflete-se na Sentence
classe.
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();
}
}
Na sua forma mais simples, pode modificar a palavra encontrada na frase usando código como o seguinte. Note que não está a atribuir um valor ao método, mas sim à expressão que o método devolve, que é o valor de retorno de referência.
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.
Um problema com este código, no entanto, é que se uma correspondência não for encontrada, o método devolve a primeira palavra. Uma vez que o exemplo não examina o valor do Boolean
argumento para determinar se um fósforo é encontrado, modifica a primeira palavra se não houver correspondência. O exemplo a seguir corrige-o substituindo a primeira palavra por si mesmo se não houver correspondência.
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.
Uma solução melhor é utilizar um método de ajuda ao qual o valor de retorno de referência é passado por referência. O método do ajudante pode então modificar o argumento que lhe foi transmitido por referência. O exemplo que se segue faz isso.
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 mais informações, consulte valores de retorno de referência.
Visual Basic 14
Pode obter o nome de cadeia não qualificado de um tipo ou membro para ser usado numa mensagem de erro sem codificar duramente uma corda. Isto permite que o seu código permaneça correto ao refactorar. Esta funcionalidade também é útil para ligar links MVC controlador de modelos e eventos alterados de propriedade.
Pode usar expressões de interpolação de cordas para construir cordas. Uma expressão de corda interpolada parece uma corda de modelo que contém expressões. Uma cadeia interpolada é mais fácil de entender em relação aos argumentos do que a Formatação Compósita.
Acesso e indexação de membros nulos
Pode testar o nulo de forma muito leve antes de efetuar uma operação de acesso ao membro (?.
) ou index (?[]
). Estes operadores ajudam-no a escrever menos código para lidar com verificações nulas, especialmente para descer em estruturas de dados. Se a referência à ópera ou objeto à esquerda for nula, as operações são nulas.
Literais de cordas multi-linha
As cordas literais podem conter sequências novas. Já não precisas do trabalho antigo de usar <xml><![CDATA[...text with newlines...]]></xml>.Value
Comentários
Pode colocar comentários após continuações implícitas de linha, expressões iniciais e entre termos de expressão LINQ.
Resolução de nomes totalmente qualificada mais inteligente
Dado código como Threading.Thread.Sleep(1000)
, Visual Basic usado para procurar o espaço de nome "Threading", descobrir que era ambíguo entre System.Threading e System.Windows. Roscar, e depois relatar um erro. Visual Basic agora considera ambos os espaços de nome possíveis juntos. Se apresentar a lista de conclusão, o editor Visual Studio lista membros de ambos os tipos na lista de conclusão.
Literales do primeiro ano
Você pode ter data literal em formato yyy-mm-dd, #2015-03-17 16:10 PM#
.
Propriedades de interface de readonly
Pode implementar propriedades de interface de readon usando uma propriedade de readwrite. A interface garante a funcionalidade mínima, e não impede que uma classe de implementação deixe a propriedade ser definida.
Para obter mais legibilidade do seu código, pode agora utilizar TypeOf
com IsNot
.
ID> de aviso de #Disable <e #Enable iD de aviso <>
Pode desativar e permitir avisos específicos para regiões dentro de um ficheiro de origem.
Melhorias de comentários de xML doc
Ao escrever comentários doc, obtém-se editor inteligente e constrói suporte para validar nomes de parâmetros, manuseamento adequado de crefs
(genéricos, operadores, etc.), coloração e refacagem.
Definições parciais de módulos e interfaces
Além de aulas e estruturas, pode declarar módulos e interfaces parciais.
#Region diretivas dentro dos órgãos de método
Você pode colocar #Region... #End delimiters da Região em qualquer lugar de um arquivo, funções internas, e até mesmo abrangendo os corpos de funções.
As definições de substituição são implicitamente sobrecarregadas
Se adicionar o Overrides
modificador a uma definição, o compilador adiciona Overloads
implicitamente para que possa escrever menos código em casos comuns.
CObj permitido em argumentos de atributos
O compilador usado para dar um erro que cObj(...) não era uma constante quando usado em construções de atributos.
Declarar e consumir métodos ambíguos de diferentes interfaces
Anteriormente, o seguinte código produziu erros que o impediram de declarar IMock
ou de ligar GetDetails
(se estes tivessem sido declarados em 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
Agora, o compilador utilizará regras normais de resolução de sobrecargas para escolher o mais adequado GetDetails
para ligar, e pode declarar relações de interface em Visual Basic como as mostradas na amostra.