Depuis la naissance du langage Visual Basic en 1991, il constitue un outil très efficace pour créer des applications. Près de 20 ans plus tard, il continue de fournir une intégration facile avec Microsoft .NET Framework, permettant aux développeurs d'écrire des applications qui couvrent les ordinateurs de bureau, les téléphones, les navigateurs et même le cloud.
Microsoft publiera ce mois-ci Visual Studio 2010, qui inclut Visual Basic version 10 (parfois appelé VB 2010 ou VB10). Cette version est la plus puissante à ce jour et inclut de nombreuses fonctionnalités permettant de gagner du temps pour aider les développeurs à en faire plus avec moins de lignes de code. Ici, vous recevrez tout le contenu nécessaire pour bien comprendre et tirer parti de Visual Basic dans Visual Studio 2010.
co-évolution
Dans le passé, Visual Basic et C# étaient développés par des équipes distinctes, ce qui entraînait souvent l'apparition de fonctionnalités d'abord dans un langage, puis dans l'autre. Par exemple, C# possède des propriétés implémentées automatiquement et des initialiseurs de collection que l'on ne trouve pas dans Visual Basic, et Visual Basic possède des fonctionnalités telles que la liaison tardive et des paramètres facultatifs que l'on ne trouve pas dans C#. Mais chaque fois qu’une langue bénéficie d’une nouvelle fonctionnalité, de nombreux clients demandent que cette fonctionnalité soit également ajoutée à l’autre langue.
Pour répondre à ce besoin, Microsoft a fusionné les équipes Visual Basic et C# pour mettre en œuvre une stratégie de co-évolution. L'objectif est de promouvoir le développement commun de ces langues. Lorsqu’une fonctionnalité majeure est introduite dans une langue, elle apparaît également dans l’autre langue. Cela ne veut pas dire que chaque fonctionnalité sera présente dans les deux langues et fonctionnera exactement de la même manière ; en fait, chaque langue a sa propre histoire, son âme et son ressenti – et il est important de préserver ces caractéristiques.
Dans .NET Framework 4, Visual Basic et C# ont fait un grand pas vers cet objectif, chacun absorbant de nombreuses fonctionnalités existantes de l'autre. Cependant, la co-évolution n’affecte pas seulement les fonctionnalités précédentes ; elle constitue également une stratégie pour le développement futur de ces langages. Dans cet esprit, .NET Framework 4 introduit de nouvelles fonctionnalités puissantes dans les deux langages, telles que le runtime de langage dynamique, les types d'interopérabilité intégrés et la variance générique, permettant aux développeurs Visual Basic et C# de tirer pleinement parti de .NET Framework.
Quoi de neuf dans Visual Basic 2010
Les nouvelles fonctionnalités de Visual Basic 2010 sont conçues pour vous aider à faire plus avec moins de lignes de code. Notre équipe de conception Visual Basic a examiné de près les endroits où les développeurs doivent généralement écrire beaucoup de code passe-partout fastidieux et a trouvé des moyens de laisser le compilateur faire le travail à la place. Bien sûr, il s’agit d’une vue d’ensemble, examinons maintenant de plus près chaque fonctionnalité.
Caractère de continuation de ligne implicite
Visual Basic est un langage orienté ligne qui utilise une syntaxe claire similaire à l'anglais pour améliorer la lisibilité. Mais cela aboutit souvent à ce que le code atteigne la limite de 80 caractères par ligne, obligeant les développeurs à faire beaucoup de défilement. Vous pouvez utiliser le caractère de soulignement pour indiquer au compilateur que le traitement de la ligne suivante doit continuer en tant que ligne actuelle (c'est-à-dire pour traiter plusieurs lignes physiques comme une seule ligne logique). Mais devoir taper le caractère de soulignement à plusieurs reprises a toujours été ennuyeux, et en fait, l'une des principales demandes de fonctionnalités depuis des années était que le compilateur résolve ce problème.
Dans Visual Basic 2010, le compilateur peut résoudre ce problème. Le compilateur sait désormais quels jetons (tels que les virgules, les parenthèses et les opérateurs) ont tendance à apparaître avant les caractères de continuation de ligne, et il insère des caractères afin que les développeurs n'aient plus besoin d'insérer de caractères. Par exemple, il n'est certainement pas logique de terminer une instruction Visual Basic par une virgule ; le compilateur le sait, donc lorsque le compilateur voit un flux de jetons tel que {virgule, enter}, il en déduit la présence d'un caractère de continuation de ligne, comme le montre la figure L'exemple en 1 est montré.
Figure 1 : Déduire les caractères de continuation de ligne
<Extension()>
Fonction FiltreParPays(
Clients ByVal comme IEnumerable (du client),
Pays ByVal As String) As IEnumerable (du client)
Requête faible =
De c Chez les clients
Où c.Country = pays
Sélectionnez <Client>
<%=
c.Nom &
, &
c.Pays
%>
</Client>
Requête de retour
Fonction de fin
Dans Visual Basic 2008, le code de la figure 1 nécessiterait 9 caractères de soulignement. Cependant, dans chacun des cas suivants, le compilateur déduit quand le caractère de soulignement est nécessaire et permet de l'ignorer :
Après l'attribut <Extension()>
après ((parenthèse gauche) dans la déclaration de méthode
après le , (virgule) du premier paramètre
avant ) (parenthèse droite) dans la déclaration de méthode
après = (signe égal)
après <%= (la balise d'ouverture d'une expression incorporée)
Après chaque esperluette (esperluette) dans le texte XML
avant %> (balise de fin de l'expression incorporée)
Cette nouvelle fonctionnalité du compilateur est particulièrement utile pour les signatures de méthodes, qui fonctionneront également correctement pour plus de 80 caractères dans l'exemple présenté (si chaque partie est sur la même ligne). Dans la figure 2, vous verrez toutes les combinaisons de balises et de positions pour lesquelles les caractères de continuation de ligne sont implicites.
Figure 2 Lorsque le caractère de continuation de ligne est implicite
marque | Avant | après |
, (virgule), . (point), > (attribut), ( { (crochet gauche), <%= (balise de début d'expression intégrée (texte XML)) | X | |
), }, ] (crochet droit), %> (balise de fin d'expression intégrée) | X | |
Tous les mots-clés LINQ : Agréger, Distinct, De, Regrouper par, Rejoindre un groupe, Rejoindre, Laisser, Trier par, Sélectionner, Sauter, Sauter pendant, Prendre, Prendre pendant, Où, Dans, Dans, Sur, Croissant, Décroissant | X | X |
Opérateur: +, -,*,/,/,^,>>,<<,Mod,&,+=,-=,*=,/=,/=,^=,>>=,<<=, & =, <, <=, >, >=, <>, est, n'est pas, comme, et, ou, Xor, et aussi, ou sinon | X | |
Avec (dans l'initialiseur d'objet) | X |
Comme vous pouvez le constater, il existe plus de 60 endroits dans la langue où le caractère de soulignement n'est pas requis. (En fait, aucun des exemples de code de cet article ne nécessite des caractères de continuation de ligne.) Bien entendu, vous pouvez toujours utiliser le caractère de soulignement, de sorte que le code des versions précédentes de Visual Basic sera toujours compilé comme prévu.
DéclarationLambda
Le terme lambda peut paraître effrayant au début, mais un lambda n'est qu'une fonction définie au sein d'une autre fonction. Visual Basic 2008 a introduit les expressions lambda avec le mot clé Function :
Dim customers As Customer() = ...
Array.FindAll (clients, fonction (c) c.Country = Canada)
Les expressions Lambda vous permettent d'exprimer la logique localement de manière granulaire et compacte sans avoir à la diviser en plusieurs méthodes. Par exemple, voici la représentation du code précédent dans Visual Basic 2005 (qui ne prend pas en charge les expressions lambda) :
Dim query = Array.FindAll(customers, AddressOf Filter)
...
Fonction Filtre (ByVal c En tant que client) En tant que booléen
Retour c.Pays = Canada
Fonction de fin
Malheureusement, les expressions lambda de Visual Basic 2008 nécessitent que l'expression renvoie une valeur, donc le code suivant :
Array.ForEach(customers, Function(c) Console.WriteLine(c.Country))
Conduira à la situation suivante :
'Compile error: Expression does not produce a value.
Console.WriteLine est une procédure Sub (void en C#), elle ne renvoie donc pas de valeur, c'est pourquoi le compilateur génère une erreur. Pour gérer cette situation, Visual Basic 2010 a introduit la prise en charge des lambdas d'instructions, qui sont des lambdas contenant une ou plusieurs instructions :
Array.ForEach(customers, Sub(c) Console.WriteLine(c.Country))
Puisque Console.WriteLine ne renvoie pas de valeur, nous pouvons simplement créer un Sub lambda au lieu d'une Function lambda. Voici un autre exemple utilisant plusieurs instructions :
Array.ForEach(customers, Sub(c)
Console.WriteLine(Nom du pays :)
Console.WriteLine(c.Pays)
Fin du sous)
Lorsque ce code s'exécute, il imprime deux lignes pour chaque client. Notez également que si vous survolez c pendant le codage, vous verrez que le compilateur déduira le type comme Customer (il est également légal de taper c As Customer pour déclarer explicitement le type). L'écriture dynamique de gestionnaires d'événements est une autre grande utilisation des instructions lambda :
AddHandler b.Click, Sub(sender As Object, e As EventArgs)
MsgBox (bouton cliqué)
'insérez ici une logique plus complexe
Fin du sous-marin
Et, en fait, vous pouvez utiliser des instructions lambdas avec une fonctionnalité introduite dans Visual Basic 2008 : la délégation libre. (Vous pouvez utiliser des délégués – des pointeurs de fonction de type sécurisé – pour exécuter plusieurs fonctions à la fois.) Cette combinaison donne une signature beaucoup plus simple :
AddHandler b.Click, Sub()
MsgBox (bouton cliqué)
'insérez ici une logique plus complexe
Fin du sous-marin
La liberté des délégués vous permet d’ignorer complètement les paramètres des gestionnaires d’événements – c’est un grand avantage, tant qu’ils ne sont pas utilisés du tout, ils ne sont donc que visuellement intrusifs.
En plus des Sub lambdas sur une seule ligne et des Sub lambdas multilignes que nous avons vus jusqu'à présent, Visual Basic 2010 prend également en charge les lambdas de fonction multilignes :
Dim query = customers.Where(Function(c)
'Renvoyer uniquement les clients qui n'ont pas été enregistrés
'insérez ici une logique plus complexe
Renvoie c.ID = -1
Fonction de fin)
Un autre aspect intéressant des instructions lambda est la façon dont elles se croisent avec les délégués anonymes introduits dans Visual Basic 2008. Les gens confondent souvent ces délégués avec les méthodes anonymes de C#, bien qu'elles ne soient pas strictement identiques. La délégation anonyme se produit lorsque le compilateur Visual Basic déduit le type de délégué en fonction de la signature de la méthode lambda :
Dim method = Function(product As String)
Si produit = Papier Alors
Retourner les unités 4,5' en stock
Autre
Renvoyez 10'10 de tout le reste
Fin si
Fonction de fin
MsgBox(méthode(Papier))
Si vous exécutez ce code, vous verrez la valeur 4,5 affichée dans la boîte de message. De plus, si vous survolez la méthode, vous verrez le texte Dim method As <Function(String) As Double>. Puisque nous n’avons pas fourni de type de délégué réel, le compilateur en générera automatiquement un comme suit :
Delegate Function $compilerGeneratedName$(product As String) As Double
C'est ce qu'on appelle un délégué anonyme car il n'apparaîtra que dans le code généré par le compilateur, et non dans le code tel qu'écrit. Notez que lorsqu'en fait aucune clause As n'est fournie pour spécifier le type de retour du lambda, le compilateur déduit le type de retour à Double. Le compilateur examinera toutes les instructions return dans le lambda et déterminera les types Double (4.5) et Integer (10) :
'Notice the As Single
Méthode Dim = Fonction (produit en tant que chaîne) en tant que simple
Si produit = Papier Alors
Retourner les unités 4,5' en stock
Autre
Renvoyez 10'10 de tout le reste
Fin si
Fonction de fin
Il exécute ensuite son algorithme de type de base et détermine qu'il peut convertir en toute sécurité 10 en Double, mais ne peut pas convertir en toute sécurité 4,5 en Integer, Double est donc le meilleur choix ;
Vous pouvez également contrôler explicitement le type de retour, auquel cas le compilateur n'essaiera pas de déduire le type. Il est très courant d'attribuer le lambda à une variable avec un type délégué explicite, plutôt que de compter sur le compilateur pour déduire le type délégué :
Dim method As Func(Of String, Single) =
Fonction (produit)
Si produit = Papier Alors
Retourner les unités 4,5' en stock
Autre
Renvoyez 10'10 de tout le reste
Fin si
Fonction de fin
Étant donné qu'un type cible explicite est fourni, il n'est pas nécessaire de déclarer As String ou As Single ; le compilateur peut déduire son existence en fonction du type délégué situé à gauche de l'instruction. Ainsi, si vous survolez le produit, vous verrez que le type déduit est String. Vous n’avez plus besoin de spécifier As Single car le type de délégué fournit déjà ces informations. Dans l'exemple précédent, la signature du délégué Func (qui est inclus avec le .NET Framework) ressemble à ceci :
Delegate Function Func(Of T, R)(ByVal param As T) As R
Il existe une petite exception, comme nous le verrons plus loin dans la section sur la variance générique.
Propriétés implémentées automatiquement
Dans Visual Basic, les propriétés sont des membres de classe qui exposent l'état d'un objet au monde extérieur. Une déclaration de propriété typique ressemble à ce qui suit :
Private _Country As String
Pays de la propriété sous forme de chaîne
Obtenir
Retour_Pays
Fin Obtenir
Définir (valeur ByVal sous forme de chaîne)
_Pays = valeur
Ensemble de fin
Propriété de fin
Un concept en fait très simple avec 10 lignes de code. Puisqu'un objet typique possède souvent des dizaines de propriétés, vous finissez par inclure beaucoup de code passe-partout dans la définition de votre classe. Pour simplifier ces tâches, Visual Basic 2010 introduit des propriétés implémentées automatiquement, qui vous permettent de définir des propriétés simples avec une seule ligne de code :
Property Country As String
Dans ce cas, le compilateur continuera à s'exécuter et générera automatiquement des getters, des setters et des champs de support. Le nom d'un champ pris en charge est toujours le nom d'un attribut précédé d'un caractère de soulignement : _Country dans cet exemple. Cette convention de dénomination garantit la compatibilité de la sérialisation binaire lors de la modification des propriétés implémentées automatiquement en propriétés normales. La sérialisation binaire continuera à fonctionner tant que les noms des champs de support seront les mêmes.
L'une des choses intéressantes que vous pouvez faire avec les propriétés implémentées automatiquement est de spécifier un initialiseur qui définit la valeur par défaut de la propriété lors de l'exécution du constructeur. Par exemple, un scénario courant avec des classes d'entités définit la clé primaire sur une valeur telle que -1 pour indiquer qu'elle est dans un état non enregistré. Le code ressemblera à ceci :
Property ID As Integer = -1
Lorsque le constructeur s'exécute, le champ de sauvegarde (_ID) est automatiquement défini sur la valeur -1. La syntaxe de l'initialiseur fonctionne également pour les types référence :
Property OrderList As List(Of Order) = New List(Of Order)
Étant donné que vous n'avez pas besoin de taper deux fois le nom du type, la ligne de code précédente peut ne pas présenter de caractéristiques Visual Basic très évidentes. La bonne nouvelle est qu'il existe une syntaxe plus courte pour les déclarations de variables régulières, cohérente avec la syntaxe autorisée par Visual Basic :
Property OrderList As New List(Of Order)
Vous pouvez même utiliser cette syntaxe avec un initialiseur d'objet pour permettre la définition d'autres propriétés :
Property OrderList As New List(Of Order) With {.Capacity = 100}
Evidemment, pour des propriétés plus complexes, une syntaxe étendue reste nécessaire. Vous pouvez toujours taper Property{Tab} pour activer l'ancien fragment de propriété. Alternativement, après avoir tapé la première ligne de la propriété, vous pouvez simplement saisir Get{Enter} et l'EDI générera la propriété à l'ancienne :
Property Name As String
Obtenir
Fin Obtenir
Définir (valeur ByVal sous forme de chaîne)
Ensemble de fin
Propriété de fin
On constate généralement : la nouvelle syntaxe des propriétés est presque identique à celle des champs publics, alors pourquoi ne pas utiliser des champs publics à la place ? Il y a plusieurs raisons :
La plupart de l'infrastructure de liaison de données .NET fonctionne en termes de propriétés plutôt qu'en termes de champs.
Une interface ne peut pas imposer la présence d'un champ ; elle peut imposer la présence d'un attribut.
Les propriétés offrent une flexibilité à plus long terme pour modifier les règles métier. Par exemple, supposons que quelqu’un introduise une règle selon laquelle les numéros de téléphone doivent comporter 10 chiffres. Cette validation ne peut pas être effectuée si elle est affectée à un champ public. Changer les champs publics en propriétés constitue un changement radical pour des scénarios tels que la sérialisation et la réflexion binaires.
Initialiseur de collection
Une pratique courante dans .NET consiste à instancier une collection, puis à la remplir en appelant la méthode Add une fois pour chaque élément :
Dim digits As New List(Of Integer)
chiffres.Add(0)
chiffres.Add(1)
chiffres.Add(2)
chiffres.Add(3)
chiffres.Add(4)
chiffres.Add(5)
chiffres.Add(6)
chiffres.Add(7)
chiffres.Add(8)
chiffres.Add(9)
Mais pour un concept fondamentalement simple, il y a beaucoup de surcharge syntaxique. Visual Basic 2010 a introduit des initialiseurs de collection pour faciliter l'instanciation des collections. Pour ce code :
Dim digits = New List(Of Integer) From {1, 2, 3, 4, 5, 6, 7, 8, 9, 0}
Le compilateur générera automatiquement tous les appels à la méthode Add. Vous pouvez également utiliser la fonctionnalité de syntaxe As New de Visual Basic :
Dim digits As New List(Of Integer) From {1, 2, 3, 4, 5, 6, 7, 8, 9, 0}
Notez que dans l'équipe Visual Basic, nous recommandons toujours d'utiliser la deuxième syntaxe (As New) plutôt que la première, car elle rend le code plus résilient aux modifications apportées au paramètre Option Infer.
Vous pouvez utiliser un initialiseur de collection sur n’importe quel type répondant aux exigences suivantes :
Vous pouvez parcourir le type à l'aide d'une instruction For Each, c'est-à-dire que le type implémente IEnumerable. (Pour une définition plus précise/détaillée des types de collections, consultez la section 10.9.3 de la spécification du langage Visual Basic sur msdn.microsoft.com/library/aa711986(VS.71).aspx).
Le type a un constructeur sans paramètre accessible (mais pas nécessairement public).
Le type a une instance ou une méthode d’extension accessible (mais pas nécessairement publique) nommée Add.
Cela signifie que vous pouvez également utiliser des initialiseurs de collection pour des types plus complexes, tels que des dictionnaires :
Dim lookupTable As New Dictionary(Of Integer, String) From
{{1, Un},
{2, Deux},
{3, Trois},
{4, Quatre}}
(Notez que même si cette instruction s'étend sur cinq lignes, il n'y a pas de caractère de soulignement.) Dans ce cas, le compilateur générera un code équivalent à l'ancienne méthode d'initialisation d'un dictionnaire :
Dim lookupTable As New Dictionary(Of Integer, String)
lookupTable.Add (1, un)
lookupTable.Add (2, deux)
lookupTable.Add (3, trois)
lookupTable.Add (4, quatre)
Le compilateur appelle la méthode Add avec deux paramètres au lieu d'un. Il sait le faire car la valeur transmise à l'initialiseur de collection se trouve entre accolades imbriquées, comme ceci : {{1, One}, {2, Two}, …}. Pour chaque ensemble d'accolades imbriquées, le compilateur tente de transmettre ces paramètres à une méthode Add compatible.
Il est également possible de fournir votre propre implémentation Add personnalisée en utilisant des méthodes d'extension :
<Extension()>
Sub Add (source ByVal en tant que IList (du client),
ByVal id sous forme d'entier,
Nom ByVal As String,
Ville ByVal sous forme de chaîne)
source.Add (Nouveau client avec
{
.ID = identifiant,
.Nom = nom,
.Ville = ville
})
Fin du sous-marin
(Regardez tous ces caractères de soulignement manquants !) Cette méthode étend tout type qui implémente IList(Of Customer), ce qui vous permet ensuite d'utiliser la nouvelle syntaxe d'initialisation de collection, comme ceci :
Dim list = New List(Of Customer) From
{
{1, Jon, Redmond},
{2, Bob, Seattle},
{3, Sally, Toronto}
}
(Ajoutez trois clients à la liste). Vous pouvez également utiliser des initialiseurs de collection avec des propriétés automatiquement implémentées :
Property States As New List(Of String) From {AL, AK, AR, AZ, ...}
tableau littéral
Outre des méthodes plus puissantes pour travailler avec les types de collections, Visual Basic 2010 fournit également de puissantes améliorations pour travailler avec des tableaux. Supposons le code suivant (fonctionne correctement dans les anciennes versions) :
Dim numbers As Integer() = New Integer() {1, 2, 3, 4, 5}
En regardant les éléments de ce tableau, il est évident que chaque élément est un entier, donc devoir imprimer l'entier deux fois dans cette ligne n'ajoute pas vraiment de valeur. Les littéraux de tableau vous permettent de créer un tableau en plaçant tous les éléments d'un tableau entre accolades et en laissant le compilateur déduire automatiquement les types :
Dim numbers = {1, 2, 3, 4, 5}
Le type des nombres n'est pas Object mais Integer() (tant que Option Infer est activé), la raison étant que le littéral du tableau se représente désormais lui-même et possède son propre type. Supposons un exemple plus complexe :
Dim numbers = {1, 2, 3, 4, 5.555}
Dans ce cas, le type de nombres sera déduit comme Double(). Le compilateur détermine le type en examinant chaque élément du tableau et en calculant le type de base, en utilisant le même algorithme évoqué précédemment pour déduire le type de retour d'une instruction lambda. Que se passe-t-il s’il n’y a pas de type de base ? Par exemple, comme indiqué dans le code suivant :
Dim numbers = {1, 2, 3, 4, 5}
Dans ce cas, la conversion d'un entier en chaîne réduira la plage de conversion (c'est-à-dire qu'une perte de données peut survenir au moment de l'exécution) et de la même manière, la conversion d'une chaîne en entier réduira également la plage de conversion. Le seul type sûr parmi lequel choisir est Object() (le compilateur générera une erreur si Option Strict est activé).
Les littéraux de tableau peuvent être imbriqués pour former des tableaux multidimensionnels ou des tableaux irréguliers :
'2-dimensional array
Matrice Dim = {{1, 0}, {0, 1}}
'tableau déchiqueté - les parenthèses forcent d'abord l'évaluation du tableau interne
Dim dentelé = { ({1, 0}), ({0, 1}) }
environnement d'exécution de langage dynamique
Bien que Visual Basic soit techniquement un langage statique par nature, il a toujours eu des fonctionnalités dynamiques très puissantes, telles que la liaison tardive. Visual Studio 2010 est livré avec une nouvelle plate-forme appelée Dynamic Language Runtime (DLR) qui facilite la création de langages dynamiques et la communication entre eux. Visual Basic 2010 a été mis à jour pour prendre entièrement en charge le DLR dans ses derniers classeurs, permettant aux développeurs d'utiliser des bibliothèques et des frameworks développés dans d'autres langages (tels que IronPython/IronRuby).
Un avantage exceptionnel de cette fonctionnalité est que syntaxiquement, rien n'a changé (en fait, pas une seule ligne de code n'a été modifiée dans le compilateur pour prendre en charge cette fonctionnalité). Les développeurs peuvent toujours effectuer des opérations de liaison tardive comme ils le faisaient dans les versions précédentes de Visual Basic. Ce qui a changé, c'est le code du runtime Visual Basic (Microsoft.VisualBasic.dll), qui reconnaît désormais l'interface IDynamicMetaObjectProvider fournie par le DLR. Si un objet implémente cette interface, le runtime Visual Basic crée un CallSite DLR et permet à l'objet et au langage qui le fournit d'injecter leur propre sémantique dans l'opération.
Par exemple, la bibliothèque standard Python contient un fichier appelé random.py, qui possède une méthode appelée shuffle qui peut être utilisée pour réorganiser aléatoirement les éléments d'un tableau. L'appel de cette méthode est simple :
Dim python As ScriptRuntime = Python.CreateRuntime()
Dim aléatoire As Object = python.UseFile (random.py)
Dim éléments = {1, 2, 3, 4, 5, 6, 7}
random.shuffle (articles)
Au moment de l'exécution, Visual Basic voit que l'objet implémente IDynamicMetaObjectProvider et passe donc le contrôle au DLR, qui communique ensuite avec Python et exécute la méthode (en passant le tableau défini dans Visual Basic en tant que paramètre à la méthode).
Il s'agit d'un exemple d'appel d'une API compatible DLR, mais les développeurs peuvent également créer leurs propres API qui utilisent cette fonctionnalité. La clé est d'implémenter l'interface IDynamicMetaObjectProvider, auquel cas les compilateurs Visual Basic et C# reconnaîtront les objets avec une sémantique dynamique spéciale. Veuillez ne pas implémenter cette interface manuellement, il est plus facile d'hériter de la classe System.Dynamic.DynamicObject (qui implémente déjà cette interface) et de remplacer seulement quelques méthodes. La figure 3 montre un exemple complet de création d'un objet dynamique personnalisé (un ensemble de propriétés qui semble créer des propriétés à la volée) et d'utilisation d'une liaison tardive Visual Basic normale pour appeler l'objet. (Pour plus d'informations sur l'utilisation de DynamicObject, lisez l'excellent article de Doug Rothaus sur blogs.msdn.com/vbteam/archive/2010/01/20/fun-with-dynamic-objects-doug-rothaus.aspx .)
Figure 3 Créer un objet dynamique personnalisé et appeler l'objet à l'aide de la liaison tardive Visual Basic
Imports System.Dynamic
ModuleModule1
Sous-principal()
Dim p comme objet = nouveau PropertyBag
p.Un = 1
p.Deux = 2
p.Trois = 3
Console.WriteLine(p.One)
Console.WriteLine(p.Deux)
Console.WriteLine (p. Trois)
Fin du sous-marin
Classe PropertyBag : hérite de DynamicObject
Valeurs privées en tant que nouveau dictionnaire (de chaîne, entier)
Fonction de remplacement publique TrySetMember (
Classeur ByVal En tant que SetMemberBinder,
Valeur ByVal comme objet) comme booléen
valeurs (classeur. Nom) = valeur
Renvoyer vrai
Fonction de fin
Fonction de remplacement publique TryGetMember(
Classeur ByVal En tant que GetMemberBinder,
Résultat ByRef Comme objet) Comme booléen
Valeurs de retour.TryGetValue(binder.Name, résultat)
Fonction de fin
Fin du cours
Module de fin
écart générique
Il s'agit d'une fonction qui peut effectivement paraître complexe au premier abord (avec des termes comme covariance et contravariance), mais elle est en réalité assez simple. Si vous avez un objet de type IEnumerable(Of Apple) et que vous souhaitez l'attribuer à IEnumerable(Of Fruit), cela devrait être légal car chaque pomme est un fruit (forcé par héritage). Malheureusement, avant Visual Basic 2010, la variance générique n'était pas prise en charge dans le compilateur, même si elle était en fait prise en charge dans le Common Language Runtime (CLR).
Jetons un coup d'œil à l'exemple de la figure 4. Dans Visual Basic 2008, le code de la figure 4 produira une erreur de compilation sur la ligne Dim activéOnly (ou, si Option Strict est désactivée, une exception d'exécution). La solution de contournement consiste à appeler la méthode d'extension .Cast comme suit :
'Old way, the call to Cast(Of Control) is no longer necessary in VB 2010
Dim activéOnly = FilterEnabledOnly(boutons.Cast(Of Control))
Cela n'est plus nécessaire car dans Visual Basic 2010, l'interface IEnumerable a été marquée comme covariante à l'aide du modificateur Out :
Interface IEnumerable(Of Out T)
...
Interface de fin
Figure 4 Exemple de variance générique
Option Strict On
Formulaire de classe publique1
Sub Form1_Load() gère MyBase.Load
Dim boutons comme nouvelle liste (de bouton) à partir de
{
Nouveau bouton avec
{
.Name = btnOk,
.Enabled = Vrai
},
Nouveau bouton avec
{
.Name = btnAnnuler,
.Enabled = Faux
}
}
Dim activéOnly = FilterEnabledOnly (boutons)
Fin du sous-marin
Fonction FilterEnabledOnly(
Contrôles ByVal comme IEnumerable (de contrôle)
) Comme IEnumerable (de contrôle)
Retour de c Dans les contrôles
Où c.Enabled = True
Fonction de fin
Fin du cours
Cela signifie que le paramètre générique T est désormais une variable (c'est-à-dire qu'il est adapté à l'héritage) et le compilateur veillera à ce que le paramètre ne soit utilisé que lorsque le type provient d'une interface. Les paramètres génériques peuvent également être des variables inverses, ce qui signifie qu'ils ne sont utilisés que là où ils sont saisis. Un type peut en réalité avoir les deux. Par exemple, le délégué Func évoqué précédemment possède à la fois des paramètres contravariants (pour ce qui est transmis) et des paramètres covariants (pour le type de retour) :
Delegate Function Func(Of In T, Out R)(ByVal param As T) As R
Vous pouvez utiliser les modificateurs In et Out sur les interfaces et les délégués personnalisés. De nombreuses interfaces et délégués courants dans .NET Framework 4 sont marqués comme variables ; les exemples courants incluent tous les délégués Action/Func, IEnumerable(Of T), IComparer(Of T), IQueryable(Of T), etc.
L'avantage de la variance générique est qu'il s'agit d'une fonctionnalité dont vous n'avez pas à vous soucier du tout : si elle fait son travail, vous ne la remarquerez jamais. Les situations qui entraînaient autrefois des erreurs du compilateur ou nécessitaient l’appel de .Cast(Of T) fonctionnent correctement dans Visual Basic 2010.
Paramètres facultatifs améliorés
Les paramètres facultatifs fournissent une fonctionnalité d'efficacité utile qui permet aux développeurs de créer des méthodes plus flexibles et d'éviter d'encombrer une classe avec de nombreuses surcharges de méthodes. Dans le passé, il y avait une légère restriction selon laquelle les paramètres facultatifs ne pouvaient pas être nuls (ni même avoir un type de structure non interne). Visual Basic 2010 vous permet désormais de définir des paramètres facultatifs de n'importe quel type de valeur :
Sub DisplayOrder(ByVal customer As Customer,
ByVal orderID sous forme d'entier,
Unités ByVal facultatives Comme entier ?
Facultatif ByVal backgroundColor As Color = Rien)
Fin du sous-marin
Dans cet exemple, les unités sont de type Nullable(Of Integer) et backgroundColor est un type de structure sans contenu, mais elles sont toujours utilisées comme paramètres facultatifs. Visual Basic 2010 offre également une meilleure prise en charge des paramètres facultatifs génériques.
Types d'interopérabilité intégrés
Une faiblesse courante des applications qui effectuent l’interopérabilité COM est la nécessité d’utiliser un assemblage d’interopérabilité primaire (PIA). Un PIA est un assembly .NET qui agit comme un wrapper appelable au moment de l'exécution (RCW) sur un composant COM et possède un GUID unique qui l'identifie. L'assembly .NET communique avec le PIA, qui effectue ensuite tout marshaling nécessaire pour déplacer les données entre COM et .NET.
Malheureusement, les PIA peuvent compliquer le déploiement car ce sont des DLL supplémentaires qui doivent être déployées sur les ordinateurs des utilisateurs finaux. Ils peuvent également entraîner des problèmes de version : par exemple, si vous souhaitez que votre application fonctionne à la fois avec Excel 2003 et Excel 2007, vous devrez déployer les deux PIA avec votre application.
La fonctionnalité de type d'interopérabilité intégrée s'intègre directement dans l'application, mais uniquement les types et les membres du PIA qui sont absolument nécessaires, il n'est donc pas nécessaire de déployer le PIA sur l'ordinateur de l'utilisateur final.
Pour activer cette fonctionnalité pour un objet existant (elle est activée par défaut pour les nouvelles références), sélectionnez la référence dans l'Explorateur de solutions et modifiez l'option Embed Interop Types dans la fenêtre Propriétés (voir Figure 5). Alternativement, si vous compilez avec le compilateur de ligne de commande Ming, utilisez le commutateur /l (ou /link) au lieu de /r et /reference.
Figure 5 Activation des types d'interopérabilité intégrés dans l'Explorateur de solutions
Après avoir activé cette fonctionnalité, l'application ne s'appuiera plus sur PIA. En fait, si vous ouvrez l'assemblage dans Reflector ou ildasm, vous remarquerez qu'il n'y a en fait aucune référence au PIA.
Objectifs multiples
La meilleure partie de toutes les fonctionnalités de Visual Basic 2010 est que vous pouvez les utiliser même dans des projets ciblant .NET Framework 2.0 via .NET Framework 3.5. Cela signifie que des fonctionnalités telles que les caractères de continuation de ligne implicites, les littéraux de tableau, les initialiseurs de collection, les lambdas d'instructions, les propriétés implémentées automatiquement, etc. seront toutes disponibles dans les projets existants sans avoir à recibler le .NET Framework 4.
L'exception concerne les types d'interopérabilité intégrés, qui reposent sur des types disponibles uniquement dans .NET Framework 4. Par conséquent, si vous ciblez les versions 2.0 à 3.5 de .NET Framework, vous ne pouvez pas utiliser cette fonctionnalité. De plus, les types marqués comme variables sont uniquement marqués tels qu'ils l'étaient dans le .NET Framework 4. Ainsi, dans l'exemple précédent, si vous ciblez les versions 2,0 à 3,5, vous devez toujours appeler .Cast(Of T). Cependant, si vous ciblez ces versions antérieures, vous pouvez créer vos propres types de variables (à l'aide des modificateurs In/Out).
Pour modifier le cadre cible actuel de votre application, double-cliquez sur Mes projets, cliquez sur l'onglet Compiler, cliquez sur Options de compilation avancées, puis sélectionnez dans la zone de liste déroulante en bas.
Il n'y a en fait aucun commutateur de ligne de commande Ming pour activer cette fonctionnalité lors de la compilation à partir de la ligne de commande Ming. En effet, le compilateur examine quel assembly fournit la définition de System.Object (généralement mscorlib) et quel framework l'assembly est ciblé, puis marque cette valeur dans l'assembly de sortie. (Le compilateur utilise ce même mécanisme lors de la génération des assemblys Silverlight.) Lorsque vous utilisez un IDE, tout cela se produit de manière transparente, vous n'avez donc généralement pas à vous inquiéter.
Bienvenue pour essayer
Comme vous pouvez le constater, Visual Basic 2010 possède de nombreuses fonctionnalités puissantes qui vous permettent d'être plus productif tout en écrivant moins de lignes de code et en laissant le compilateur faire plus de travail. Dans cet article, je n'ai abordé que les fonctionnalités du langage, mais il existe d'innombrables améliorations intéressantes apportées à l'EDI Visual Basic 2010. Certaines améliorations sont répertoriées ci-dessous :
Accédez à
Surligner les citations
généré par l'utilisation
Meilleur IntelliSense (correspondance de sous-chaînes, recherche de camelcase, modèles de suggestion – utile pour tester votre style de développement en premier)
Prise en charge de plusieurs moniteurs
Zoom
L'équipe Visual Basic est impatiente de connaître vos commentaires sur nos efforts visant à améliorer Visual Basic. Veuillez donc nous envoyer vos commentaires et questions sur Microsoft Connect. Pour en savoir plus sur le langage et les fonctionnalités de l'IDE, consultez le contenu sur msdn.com/vbasic, qui comprend des articles, des exemples et des vidéos pratiques. Bien sûr, la meilleure façon d’apprendre est de se familiariser avec le produit et de l’utiliser. Il est donc temps de l’installer et de l’essayer.