Cette rubrique liste les noms des principales fonctionnalités de chaque version de Visual Basic et décrit en détail les fonctionnalités nouvelles et améliorées des dernières versions du langage.
Version actuelle
Visual Basic 16.9 / Visual Studio 2019 version 16.9
Pour connaître les nouvelles fonctionnalités, consultez Visual Basic 16.9.
Vous pouvez télécharger le dernier Kit de développement logiciel (SDK) .NET à partir de la page de téléchargements .NET.
Versions précédentes
Visual Basic 16.0 / Visual Studio 2019 version 16.0
Pour les nouvelles fonctionnalités, consultez Visual Basic 16.0.
Visual Basic 15.5 / Visual Studio 2017 version 15.5
Pour les nouvelles fonctionnalités, consultez Visual Basic 15.5.
Visual Basic 15.3 / Visual Studio 2017 version 15.3
Pour connaître les nouvelles fonctionnalités, consultez Visual Basic 15.3.
Visual Basic 15 / Visual Studio 2017
Pour connaître les nouvelles fonctionnalités, consultez Visual Basic 2017.
Visual Basic / Visual Studio 2015
Pour les nouvelles fonctionnalités, consultez Visual Basic 14.
Visual Basic / Visual Studio 2013
Aperçus technologiques de la .NET Compiler Platform (« Roslyn »)
Visual Basic / Visual Studio 2012
Mots clés Async et await, itérateurs, attributs des informations de l’appelant
Visual Basic, Visual Studio 2010
Propriétés implémentées automatiquement, initialiseurs de collection, continuation de ligne implicite, variance co/contra générique, dynamique, accès de l’espace de noms global
Visual Basic / Visual Studio 2008
Language Integrated Query (LINQ), littéraux XML, inférence de type local, initialiseurs d’objet, types anonymes, méthodes d’extension, inférence de type var local, expressions lambda, opérateur if, méthodes partielles, types de valeur nullable
Visual Basic / Visual Studio 2005
Type My et types d’assistance (accès à l’application, ordinateur, système de fichiers, réseau)
Visual Basic / Visual Studio .NET 2003
Opérateurs de décalage de bits, déclaration de variable de boucle
Visual Basic / Visual Studio .NET 2002
Première version de Visual Basic .NET
Visual Basic 16.9
Visual Basic 16.9 permet de consommer des propriétés init uniquement.
Visual Basic 16.0
Visual Basic 16.0 se concentre sur la fourniture de davantage de fonctionnalités du runtime Visual Basic (microsoft.visualbasic.dll) à .NET Core et est la première version de Visual Basic axée sur .NET Core. De nombreuses parties du runtime Visual Basic dépendent de WinForms et celles-ci seront ajoutées dans une version ultérieure de Visual Basic.
Commentaires autorisés dans d’autres emplacements dans les instructions
Dans Visual Basic 15.8 et versions antérieures, les commentaires sont autorisés uniquement sur des lignes vides, à la fin d’une instruction ou à des emplacements spécifiques dans une instruction où une continuation de ligne implicite est autorisée. À compter de Visual Basic 16.0, les commentaires sont également autorisés après des continuations de ligne explicites et dans une instruction sur une ligne commençant par un espace suivi d’un trait de soulignement.
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
Conversion optimisée de valeurs à virgule flottante en valeurs entières
Dans les versions précédentes de Visual Basic, la conversion de valeurs Double et Single en entiers offrait des performances relativement médiocres. Visual Basic 15.8 améliore considérablement les performances des conversions de valeurs à virgule flottante en entiers quand vous passez la valeur retournée par n’importe laquelle des méthodes suivantes à l’une des fonctions de conversion d’entiers Visual Basic intrinsèques (CByte, CShort, CInt, CLng, CSByte, CUShort, CUInt, CULng), ou si la valeur retournée par n’importe laquelle des méthodes suivantes est implicitement castée en un type intégral type quand Option Strict est défini sur Off :
Cette optimisation permet au code de s’exécuter plus rapidement (jusqu’à deux fois plus rapidement pour le code qui effectue un grand nombre de conversions en types d’entier). L’exemple suivant illustre certains appels de méthode simples qui sont affectés par cette optimisation :
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
Notez que cette opération tronque les valeurs à virgule flottante au lieu de les arrondir.
Dans Visual Basic 15.3 et antérieur, lorsqu’un appel de méthode incluait des arguments par position et par nom, les arguments positionnels devaient précéder les arguments nommés. À compter de Visual Basic 15.5, les arguments nommés et positionnels peuvent apparaître dans n’importe quel ordre, pourvu que tous les arguments jusqu'au dernier argument positionnel soient dans la position correcte. C’est particulièrement utile lorsque des arguments nommés sont utilisés pour rendre le code plus lisible.
Par exemple, dans l’appel de méthode suivant un argument nommé est entouré de deux arguments positionnels. L’argument nommé indique clairement que la valeur 19 représente un âge.
Cette nouvelle combinaison de mots clés définit un membre qui est accessible par tous les membres de sa classe conteneur ainsi que par des types dérivés de la classe conteneur, mais uniquement s’ils se trouvent également dans l’assembly conteneur. Étant donné que les structures ne peuvent pas être héritées, Private Protected peut uniquement être appliqué aux membres d’une classe.
Séparateur hex/binaire/octal de début
Dans Visual Basic 2017, la prise en charge du caractère de soulignement (_) comme séparateur numérique a été ajoutée. Depuis Visual Basic 15.5, vous pouvez utiliser le caractère de soulignement comme séparateur de début entre le préfixe et les chiffres hexadécimaux, binaires ou octaux. L’exemple suivant utilise un séparateur numérique de début pour définir 3,271,948,384 comme un nombre hexadécimal :
Dim number As Integer = &H_C305_F860
Pour utiliser le caractère de soulignement comme séparateur de début, vous devez ajouter l’élément suivant à votre fichier de projet Visual Basic (*.vbproj) :
Lorsque vous affectez la valeur des éléments de tuple à partir de variables, Visual Basic déduit le nom de ces éléments des noms de variables correspondants ; vous n’avez donc pas besoin de nommer explicitement un élément de tuple. L’exemple suivant utilise l’inférence pour créer un tuple de trois éléments nommés, state, stateName et 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
Commutateurs de compilation supplémentaires
Le compilateur de ligne de commande de Visual Basic prend à présent en charge les options de compilation -refout et -refonly pour contrôler la sortie des assemblys de référence. -refout définit le répertoire de sortie de l’assembly de référence, tandis que -refonly spécifie que la compilation doit générer uniquement un assembly de référence.
Les tuples sont une structure de données légère qui est le plus souvent utilisée pour retourner plusieurs valeurs à partir d’un seul appel de méthode. En règle générale, pour retourner plusieurs valeurs à partir d’une méthode, vous devez effectuer l’une des opérations suivantes :
Définir un type personnalisé (Class ou Structure). Il s’agit d’une solution lourde.
Définir un ou plusieurs paramètres ByRef, en plus de retourner une valeur à partir de la méthode.
La prise en charge des tuples par Visual Basic vous permet de définir rapidement un tuple, d’affecter éventuellement des noms de sémantique à ses valeurs et de récupérer rapidement ses valeurs. L’exemple suivant encapsule un appel à la méthode TryParse et retourne un 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
Vous pouvez ensuite appeler la méthode et gérer le tuple retourné avec du code comme celui-ci.
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
Littéraux binaires et séparateurs de chiffres
Vous pouvez définir un littéral binaire à l’aide du préfixe &B ou &b. Vous pouvez aussi utiliser le trait de soulignement, _, comme séparateur numérique pour améliorer la lisibilité. L’exemple suivant utilise les deux fonctionnalités pour affecter une valeur Byte et l’afficher sous la forme d’un nombre décimal, hexadécimal et binaire.
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)
À compter de C# 7.0, C# prend en charge les valeurs de retour de référence. Autrement dit, quand la méthode d’appel reçoit une valeur retournée par référence, elle peut modifier la valeur de la référence. Visual Basic ne vous autorise pas à créer des méthodes avec des valeurs de retour de référence, mais vous permet d’utiliser et de modifier ces valeurs.
Par exemple, la classe Sentence suivante écrite en C# inclut une méthode FindNext qui recherche le mot suivant dans une phrase qui commence par une sous-chaîne spécifiée. La chaîne est retournée comme valeur de retour de référence et une variable Boolean passée par référence à la méthode indique si la recherche a réussi. Cela signifie qu’en plus de lire la valeur retournée, l’appelant peut également le modifier et cette modification est reflétée dans la 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();
}
}
Sous sa forme la plus simple, vous pouvez modifier le mot trouvé dans la phrase à l’aide de code semblable au suivant. Notez que vous n’affectez pas de valeur à la méthode, mais plutôt à l’expression retournée par la méthode, qui est la valeur de retour de référence.
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.
Ce code pose cependant un problème : si aucune correspondance n’est trouvée, la méthode retourne le premier mot. Comme l’exemple n’examine pas la valeur de l’argument Boolean pour déterminer si une correspondance est trouvée, il modifie le premier mot en l’absence de correspondance. L’exemple suivant corrige ce comportement en remplaçant le premier mot par lui-même en l’absence de correspondance.
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.
Une meilleure solution consiste à utiliser une méthode d’assistance à laquelle la valeur de retour de référence est passée par référence. La méthode d’assistance peut ensuite modifier l’argument qui lui est passé par référence. L’exemple suivant effectue cette opération.
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.
Vous pouvez obtenir le nom de chaîne non qualifié d’un type ou membre et l’utiliser dans un message d’erreur sans effectuer de codage irréversible de chaîne. Votre code reste alors correct lors de la refactorisation. Cette fonctionnalité est également utile pour placer des liens MVC modèle-vue-contrôleur et activer des événements de modification de propriété.
Vous pouvez utiliser des expressions d’interpolation de chaîne pour construire des chaînes. Une expression de chaîne interpolée s’apparente à une chaîne de modèle contenant des expressions. Les arguments d’une chaîne interpolée sont plus compréhensibles que dans une Composite Formatting.
Vous pouvez rechercher les valeurs Null à l’aide d’une syntaxe très légère avant d’effectuer une opération d’accès aux membres (?.) ou d’indexation (?[]). Ils permettent d'écrire moins de code pour gérer les vérifications Null, notamment pour l'exploration des structures de données. Si la référence objet ou l’opérande gauche est Null, l’opération renvoie la valeur Null.
Les littéraux de chaîne peuvent contenir des séquences de saut de ligne. Il n’est plus nécessaire de passer par la méthode <xml><![CDATA[...text with newlines...]]></xml>.Value.
Commentaires
Vous pouvez placer des commentaires après les continuations de lignes implicites, dans les expressions d’initialiseur et dans les termes d’expression LINQ.
Résolution de noms complète plus intelligente
En présence de code tel que Threading.Thread.Sleep(1000), Visual Basic recherchait l’espace de noms « Threading », détectait l’ambiguïté entre System.Threading et System.Windows.Threading, et signalait une erreur. Visual Basic prend désormais en compte les deux espaces de noms possibles. Lorsque vous affichez la liste de saisie semi-automatique, les membres de ces deux types y sont recensés par l’éditeur Visual Studio.
Littéraux de date pour la première année
Vous pouvez avoir des littéraux de date au format aaaa-mm-jj, #2015-03-17 16:10 PM#.
Propriétés de l’interface en lecture seule
Vous pouvez implémenter des propriétés d’interface en lecture seule à l’aide d’une propriété readwrite. L’interface garantit les fonctionnalités minimales et n’empêche pas une classe d’implémentation d’autoriser la définition de la propriété.
Vous pouvez désactiver et activer des avertissements spécifiques pour les zones d’un fichier source.
Améliorations de la fonctionnalité de commentaires de document XML
Lorsque vous écrivez des commentaires de document, vous bénéficiez d’un éditeur intelligent et de la prise en charge de version pour la validation des noms de paramètres, le gestion appropriée des crefs (génériques, opérateurs, etc.), la colorisation et la refactorisation.
Vous pouvez placer des délimiteurs #Region…#End Region n’importe où dans un fichier, dans des fonctions, ou encore répartis à différents endroits du corps d’une fonction.
Si vous ajoutez le modificateur Overrides à une définition, le compilateur ajoute Overloads de manière implicite, de sorte que vous pouvez taper moins de code dans les situations courantes.
CObj autorisé dans les arguments d’attributs
Le compilateur signalait l’erreur indiquant que CObj(...) n’est pas une constante lorsqu’il est utilisé dans les constructions d’attribut.
Déclaration et consommation de méthodes ambiguës à partir de différentes interfaces
Auparavant, le code suivant générait des erreurs qui vous empêchaient de déclarer IMock ou d’appeler GetDetails (s’ils avaient été déclarés 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
À présent, le compilateur utilise les règles de résolution de surcharge normales pour choisir le GetDetails à appeler le plus approprié, et vous pouvez déclarer des relations d’interface dans Visual Basic comme indiqué dans l’exemple.
Utilisez les fonctionnalités de la bibliothèque de classes .NET en appelant des méthodes qui retournent des valeurs, acceptent des paramètres d’entrée, etc.