Archives par étiquette : VB IsNot C#

image

VB et les StackOverFlowException

Je ne mets malheureusement quasiment plus les mains dans le code, mais j’ai eu le plaisir aujourd’hui de découvrir une particularité de VB.net qui m’a fait bondir au plafond et qui m’a laissé plus perplexe.

En effet à la vision de ce code :

image

J’ai été outré de découvrir que l’appel à cette propriété ne lève pas une StackOverFlowException.

L’appel à la propriété renvoie la valeur 0 sans autre forme de procès, sans exception, sans tousser, ni avertissement pour m’indiquer “hey ! mon garçon t’es sûr de vouloir faire ça ?”

Après avoir comme à mon habitude crié au loup, et pensé qu’il s’agissait d’un bug du compilateur ou de la CLR, j’ai essayé de comprendre par quel miracle le comportement rencontré pouvait se justifier.

Un petit tour par dotPeek et voilà le résultat :

image

Nouveau sursaut, j’en discute avec le leader technique de l’équipe qui est aussi perplexe que moi, et j’essaie de trouver la raison (certainement historique) pour laquelle nous avons ce comportement en VB, et rien choux blanc.

Comme à chaque fois que j’ai des questions dirons-nous particulières à propos des langages, j’ai donc contacté mon ami Jb Evain, qui après avoir pressenti que le sujet allait être rigolo à trouver l’explication de ce fonctionnement :

C’est tout à fait normal et même logique !

Il ne faut pas oublier que nous avons la possibilité en VB de faire ce type de code :

image

Nous pouvons en effet définir la valeur de retour d’une fonction en utilisant le nom de celle-ci.

La grosse différence avec le mot clé Return étant que le Return interrompt l’exécution de la méthode en cours, alors que ce n’est pas le cas dans l’exemple ci-dessous :

image

En effet, le code suivant l’affectation de la valeur de retour est bien exécuté.

Et si l’on reprend notre exemple, je pense que vous avez déjà compris qu’en réalité le code donné en exemple :

image

est en réalité équivalent à celui-là

image

ce qui explique la non levée d’une StackOverflowException !

image

L’accès aux backing fields des propriétés au-implémentées

Dans la série des VB IsNot C#, je vous propose aujourd’hui une différence d’implémentation des propriétés auto-implémentées en C# et en VB.

C’est avec une légère surprise que je viens de redécouvrir qu’en VB, il est tout à fait possible d’accéder directement aux champs privés générés par le compilateur lors de la création d’une propriété auto-implémentée :

image

Par convention, le champ est préfixée via un underscore, il ainsi tout à fait possible d’y accéder.

Alors qu’en C#, le compilateur fait en sorte que l’on ne puisse pas directement y accéder.

A noter que ce champ privé n’apparait pas dans l’intellisense lorsque l’on essaye d’y accéder.

Par contre le Go To Definition proposé par Visual Studio highlight bien la propriété Lastname lorsqu’on l’applique au champ privé. Donc même si on ne voit pas la déclaration on peut deviner la provenance de ce champ.

ReSharper reste quand à lui un peu perdu et ne sait pas trop d’où vient ce champ.

En plus d’être un peu perturbant car on peut ne pas voir d’un coup d’œil d’où vient ce champ. Cela peut poser problème lorsque l’on souhaite déclarer un champ qui porte le même nom que celui généré par le compilateur :

image

Heureusement le compilateur propose un message bien plus compréhensible :

image

image

Nothing est différent de null

Une des différences les plus importantes entre le VB et le C# est la gestion de la nullité des types.

En VB, on utilise le mot clé Nothing et contrairement à ce que beaucoup de développeurs VB pensent,

le mot clé Nothing n’a (presque) rien à voir avec le null tel que l’on peut le connaitre dans la plupart des langages.

En effet, en VB le Nothing équivaut à Default.

La différence est très importante notamment pour les types valeurs, puisqu’il est tout à fait possible d’assigner Nothing à un type valeur ! Le type prend alors sa valeur par défaut, comme 0 pour les types numériques, ou Date.DateMin pour les dates :

image

 

Bien évidemment, pour les types références, la valeur affectée sera l’équivalent d’un null puisqu’aucune instance n’est créé lors de l’affectation de Nothing.

Pour rappel si l’on essaie de faire “la même chose” en C#, on se retrouve très justement avec une erreur de compilation :

image

Dans le prochain post, nous verrons l’impact de cette différence sur les tests d’égalité à Nothing.