Comment les paramètres facultatifs de VB.NET fonctionnent-ils sous le capot? Sont-ils conformes à CLS?

StackOverflow https://stackoverflow.com/questions/104068

  •  01-07-2019
  •  | 
  •  

Question

Disons que nous avons la déclaration de méthode suivante:

Public Function MyMethod(ByVal param1 As Integer, _
    Optional ByVal param2 As Integer = 0, _
    Optional ByVal param3 As Integer = 1) As Integer

    Return param1 + param2 + param3
End Function

Comment VB.NET fait-il que les paramètres optionnels fonctionnent dans les limites du CLR? Les paramètres facultatifs sont-ils conformes à CLS?

Était-ce utile?

La solution

Fait intéressant, il s'agit du code C # décompilé, obtenu via un réflecteur.

public int MyMethod(int param1, 
                   [Optional, DefaultParameterValue(0)] int param2, 
                   [Optional, DefaultParameterValue(1)] int param3)
{
    return ((param1 + param2) + param3);
}

Notez les attributs Optional et DefaultParameterValue. Essayez de les mettre dans les méthodes C #. Vous constaterez que vous devez toujours transmettre des valeurs à la méthode. En code VB cependant, il est devenu Default! Cela étant dit, je n'ai personnellement jamais utilisé Default, même en code VB. Cela ressemble à un hack. La surcharge de méthode me convient parfaitement.

Par défaut, cela aide quand on utilise Excel Interop, ce qui est très pénible à utiliser dès la sortie de la boîte en C #.

Autres conseils

Contrairement à la croyance populaire, les paramètres facultatifs semblent être conformes à CLS. (Cependant, ma vérification principale consistait à marquer l'assembly, la classe et la méthode avec l'attribut CLSCompliant, défini sur True.)

Alors, à quoi cela ressemble-t-il dans MSIL?

.method public static int32  MyMethod(int32 param1,
                                      [opt] int32 param2,
                                      [opt] int32 param3) cil managed
{
  .custom instance void [mscorlib]System.CLSCompliantAttribute::.ctor(bool) = ( 01 00 01 00 00 ) 
  .param [2] = int32(0x00000000)
  .param [3] = int32(0x00000001)
  // Code size       11 (0xb)
  .maxstack  2
  .locals init ([0] int32 MyMethod)
  IL_0000:  nop
  IL_0001:  ldarg.0
  IL_0002:  ldarg.1
  IL_0003:  add.ovf
  IL_0004:  ldarg.2
  IL_0005:  add.ovf
  IL_0006:  stloc.0
  IL_0007:  br.s       IL_0009
  IL_0009:  ldloc.0
  IL_000a:  ret
} // end of method Module1::MyMethod

Notez les marques [opt] sur les paramètres - MSIL le supporte de manière native, sans aucun piratage. (Contrairement au support de MSIL pour le mot clé statique de VB, qui est un autre sujet.)

Alors, pourquoi ne sont-ils pas en C #? Je ne peux pas répondre à cette question, mis à part ma spéculation selon laquelle il pourrait s'agir d'un manque présumé de demande. Ma propre préférence a toujours été de spécifier les paramètres, même s'ils étaient facultatifs. Pour moi, le code est plus propre et plus facile à lire. (Si certains paramètres sont omis, je cherche souvent une surcharge correspondant à la signature visible. Ce n’est que lorsque je ne parviens pas à en trouver une que je me rends compte que des paramètres facultatifs sont impliqués.)

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top