Nouveautés de Visual Basic

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.

Visual Basic 15.5

Arguments nommés non placés en position de fin

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.

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

Private Protected modificateur d’accès membre

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) :

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

Visual Basic 15.3

Inférence de tuple nommée

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.

Visual Basic 15

Tuples

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)      

Pour plus d’informations, consultez la section « Affectations de littéraux » des types de données Byte, Integer, Long, Short, SByte, UInteger, ULong et UShort.

Prise en charge des valeurs de retour de référence C#

À 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.

Pour plus d’informations, consultez Valeurs de retour de référence.

Visual Basic 14

NameOf

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é.

Interpolation de chaîne

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.

Accès et indexation des membres conditionnels Null

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.

Littéraux de chaîne multiligne

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é.

TypeOf <expr> IsNot <type>

Pour une meilleure lisibilité du code, vous pouvez maintenant utiliser TypeOf avec IsNot.

ID d’avertissement <> #Disable et ID d’avertissement <de #Enable>

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.

Définitions de module et d’interface partielles

En plus des classes et structures, vous pouvez déclarer des interfaces et des modules partiels.

directives #Region à l’intérieur des corps de méthode

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.

Les définitions de substitutions sont des surcharges implicites

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.

Voir aussi