Note
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de vous connecter ou de modifier les répertoires.
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de changer de répertoire.
Cette page répertorie certains problèmes courants qui peuvent se produire lors de l’utilisation de procédures.
Retour d’un type de tableau à partir d’une procédure de fonction
Si une procédure retourne un Function type de données de tableau, vous ne pouvez pas utiliser le Function nom pour stocker des valeurs dans les éléments du tableau. Si vous tentez de le faire, le compilateur l’interprète comme un appel à l’objet Function. L’exemple suivant génère des erreurs de compilateur :
Function AllOnes(n As Integer) As Integer()
For i As Integer = 1 To n - 1
' The following statement generates a COMPILER ERROR.
AllOnes(i) = 1
Next
' The following statement generates a COMPILER ERROR.
Return AllOnes()
End Function
L’instruction AllOnes(i) = 1 génère une erreur du compilateur, car elle semble appeler AllOnes avec un argument du type de données incorrect (un scalaire Integer au lieu d’un Integer tableau). L’instruction Return AllOnes() génère une erreur du compilateur, car elle semble appeler AllOnes sans argument.
Approche correcte : Pour pouvoir modifier les éléments d’un tableau à renvoyer, définissez un tableau interne en tant que variable locale. L’exemple suivant compile sans erreur :
Function AllOnes(n As Integer) As Integer()
Dim iArray(n - 1) As Integer
For i = 0 To n - 1
iArray(i) = 1
Next
Return iArray
End Function
Argument non modifié par appel de procédure
Si vous envisagez d’autoriser une procédure à modifier un élément de programmation sous-jacent à un argument dans le code appelant, vous devez le transmettre par référence. Toutefois, une procédure peut accéder aux éléments d’un argument de type référence même si vous la transmettez par valeur.
Variable sous-jacente. Pour permettre à la procédure de remplacer la valeur de l’élément de variable sous-jacent lui-même, la procédure doit déclarer le paramètre ByRef. En outre, le code appelant ne doit pas placer l’argument entre parenthèses, car cela remplacerait le
ByRefmécanisme de passage.Éléments de type référence. Si vous déclarez un paramètre ByVal, la procédure ne peut pas modifier l’élément de variable sous-jacent lui-même. Toutefois, si l’argument est un type référence, la procédure peut modifier les membres de l’objet vers lequel il pointe, même s’il ne peut pas remplacer la valeur de la variable. Par exemple, si l’argument est une variable de tableau, la procédure ne peut pas lui affecter un nouveau tableau, mais elle peut modifier un ou plusieurs de ses éléments. Les éléments modifiés sont reflétés dans la variable de tableau sous-jacente dans le code appelant.
L’exemple suivant définit deux procédures qui prennent une variable de tableau par valeur et fonctionnent sur ses éléments. La procédure increase en ajoute simplement une à chaque élément. La procédure replace affecte un nouveau tableau au paramètre a() , puis en ajoute un à chaque élément. Toutefois, la réaffectation n’affecte pas la variable de tableau sous-jacente dans le code appelant, car a() elle est déclarée ByVal.
Public Sub increase(ByVal a() As Long)
For j As Integer = 0 To UBound(a)
a(j) = a(j) + 1
Next j
End Sub
Public Sub replace(ByVal a() As Long)
Dim k() As Long = {100, 200, 300}
a = k
For j As Integer = 0 To UBound(a)
a(j) = a(j) + 1
Next j
End Sub
L’exemple suivant effectue des appels vers increase et replace:
Dim n() As Long = {10, 20, 30, 40}
Call increase(n)
MsgBox("After increase(n): " & CStr(n(0)) & ", " &
CStr(n(1)) & ", " & CStr(n(2)) & ", " & CStr(n(3)))
Call replace(n)
MsgBox("After replace(n): " & CStr(n(0)) & ", " &
CStr(n(1)) & ", " & CStr(n(2)) & ", " & CStr(n(3)))
Le premier MsgBox appel affiche « After increase(n) : 11, 21, 31, 41 ». Étant donné qu’il n s’agit d’un type référence, increase peut modifier ses membres, même s’il est passé ByVal.
Le deuxième MsgBox appel affiche « After replace(n) : 11, 21, 31, 41 ». Comme n il est passé ByVal, replace ne peut pas modifier la variable n en lui affectant un nouveau tableau. Lorsque vous replace créez la nouvelle instance k de tableau et l’attribue à la variable alocale, elle perd la référence à n passer par le code appelant. Lorsqu’il incrémente les membres a, seul le tableau k local est affecté.
Approche correcte : Pour pouvoir modifier un élément de variable sous-jacent lui-même, transmettez-le par référence. L’exemple suivant montre la modification de la déclaration de ce qui lui permet de replace remplacer un tableau par un autre dans le code appelant :
Public Sub replace(ByRef a() As Long)
Impossible de définir une surcharge
Si vous souhaitez définir une version surchargée d’une procédure, vous devez utiliser le même nom, mais une signature différente. Si le compilateur ne peut pas différencier votre déclaration d’une surcharge avec la même signature, elle génère une erreur.
La signature d’une procédure est déterminée par le nom de la procédure et la liste des paramètres. Chaque surcharge doit avoir le même nom que toutes les autres surcharges, mais doit différer de toutes ces surcharges dans au moins l’un des autres composants de la signature. Pour plus d’informations, consultez Surcharge de procédure.
Les éléments suivants, même s’ils se rapportent à la liste des paramètres, ne sont pas des composants de la signature d’une procédure :
- Mots clés de modificateur de procédure, tels que
Public,SharedetStatic. - Noms de paramètres.
- Mots clés de modificateur de paramètre, tels que
ByRefetOptional. - Type de données de la valeur de retour (à l’exception d’un opérateur de conversion).
Vous ne pouvez pas surcharger une procédure en variant un ou plusieurs des éléments précédents.
Approche correcte : Pour pouvoir définir une surcharge de procédure, vous devez varier la signature. Étant donné que vous devez utiliser le même nom, vous devez varier le nombre, l’ordre ou les types de données des paramètres. Dans une procédure générique, vous pouvez varier le nombre de paramètres de type. Dans un opérateur de conversion (opérateur CType), vous pouvez varier le type de retour.
Résolution de surcharge avec des arguments Facultatifs et ParamArray
Si vous surchargez une procédure avec un ou plusieurs paramètres facultatifs ou un paramètre ParamArray , vous devez éviter de dupliquer l’une des surcharges implicites. Pour plus d’informations, consultez Considérations relatives aux procédures de surcharge.
Appel de la version incorrecte d’une procédure surchargée
Si une procédure comporte plusieurs versions surchargées, vous devez être familiarisé avec toutes leurs listes de paramètres et comprendre comment Visual Basic résout les appels entre les surcharges. Sinon, vous pouvez appeler une surcharge autre que celle prévue.
Lorsque vous avez déterminé la surcharge que vous souhaitez appeler, veillez à observer les règles suivantes :
- Indiquez le nombre correct d’arguments et dans l’ordre correct.
- Dans l’idéal, vos arguments doivent avoir exactement les mêmes types de données que les paramètres correspondants. Dans tous les cas, le type de données de chaque argument doit s’élargir à celui de son paramètre correspondant. Cela est vrai même avec l’instruction Option Strict définie sur
Off. Si une surcharge nécessite une conversion étroite de votre liste d’arguments, cette surcharge n’est pas éligible à l’appel. - Si vous fournissez des arguments qui nécessitent un élargissement, rendez leurs types de données aussi proches que possible des types de données de paramètre correspondants. Si deux surcharges ou plus acceptent vos types de données d’argument, le compilateur résout votre appel à la surcharge qui appelle le moins de quantité d’élargissement.
Vous pouvez réduire le risque d’incompatibilités de type de données à l’aide du mot clé de conversion de fonction CType lors de la préparation de vos arguments.
Échec de la résolution de surcharge
Lorsque vous appelez une procédure surchargée, le compilateur tente d’éliminer toutes les surcharges, mais l’une des surcharges. Si elle réussit, elle résout l’appel à cette surcharge. S’il élimine toutes les surcharges ou s’il ne peut pas réduire les surcharges éligibles à un candidat unique, il génère une erreur.
L’exemple suivant illustre le processus de résolution de surcharge :
Overloads Sub z(ByVal x As Byte, ByVal y As Double)
End Sub
Overloads Sub z(ByVal x As Short, ByVal y As Single)
End Sub
Overloads Sub z(ByVal x As Integer, ByVal y As Single)
End Sub
Dim r, s As Short
Call z(r, s)
Dim p As Byte, q As Short
' The following statement causes an overload resolution error.
Call z(p, q)
Dans le premier appel, le compilateur élimine la première surcharge, car le type du premier argument (Short) se limite au type du paramètre correspondant (Byte). Il élimine ensuite la troisième surcharge, car chaque type d’argument dans la deuxième surcharge (Short et Single) s’étend sur le type correspondant dans la troisième surcharge (Integer et Single). La deuxième surcharge nécessite moins d’élargissement, de sorte que le compilateur l’utilise pour l’appel.
Dans le deuxième appel, le compilateur ne peut pas éliminer les surcharges sur la base d’un rétrécissement. Il élimine la troisième surcharge pour la même raison que dans le premier appel, car elle peut appeler la deuxième surcharge avec moins d’élargissement des types d’arguments. Toutefois, le compilateur ne peut pas résoudre entre les premières et deuxième surcharges. Chacun a un type de paramètre défini qui s’élargit au type correspondant dans l’autre (Byte à Short, mais Single à Double). Le compilateur génère donc une erreur de résolution de surcharge.
Approche correcte : Pour pouvoir appeler une procédure surchargée sans ambiguïté, utilisez la fonction CType pour faire correspondre les types de données d’argument aux types de paramètres. L’exemple suivant montre un appel à z ce qui force la résolution à la deuxième surcharge.
Call z(CType(p, Short), CType(q, Single))
Résolution de surcharge avec des arguments Facultatifs et ParamArray
Si deux surcharges d’une procédure ont des signatures identiques, sauf que le dernier paramètre est déclaré Facultatif dans un et ParamArray dans l’autre, le compilateur résout un appel à cette procédure en fonction de la correspondance la plus proche. Pour plus d’informations, consultez La résolution de surcharge.