Vous êtes nouveau sur Developpez.com ? Créez votre compte ou connectez-vous afin de pouvoir participer !

Vous devez avoir un compte Developpez.com et être connecté pour pouvoir participer aux discussions.

Vous n'avez pas encore de compte Developpez.com ? Créez-en un en quelques instants, c'est entièrement gratuit !

Si vous disposez déjà d'un compte et qu'il est bien activé, connectez-vous à l'aide du formulaire ci-dessous.

Identifiez-vous
Identifiant
Mot de passe
Mot de passe oublié ?
Créer un compte

L'inscription est gratuite et ne vous prendra que quelques instants !

Je m'inscris !

C# s'enrichit d'un safe navigator operator
à l'image de Groovy, l'opérateur «?.» fait son entrée

Le , par Arsene Newman

70PARTAGES

6  0 
C#, l'un des nombreux apports de Microsoft au développement informatique, figure actuellement parmi les langages les plus populaires selon l'index TIOBE, nul doute que son succès est dû au succès conjoint des systèmes d'exploitation Microsoft et de la plate-forme .Net, toutefois il demeure possible que son succès soit relatif à son équipe de développement qui reste à l'écoute de sa communauté et met à sa disposition un système de retour d'expérience (FeedBack) tel que www.uservoice.com.

C'est ainsi donc qu'il a été décidé d'introduire le nouvel opérateur «?.» au langage C#, après que cette suggestion ait perçu plus de 4.313 votes favorables. Appelé aussi en anglais Safe Navigation Operator, l'opérateur «?.» permet de vérifier si la référence à un membre d'une classe est égale à Null au lieu de générer une exception de type NullReferenceException, économisant par la même occasion plusieurs lignes de code au programmeur.

La force de l'opérateur prend tout son sens, lorsqu'il s'agit d'une référence à un membre d'une classe, qui est membre d'une autre classe et ainsi de suite, dans ce genre de situation il s’avère plus difficile de détecter l'origine de l'exception, un exemple vaut mieux qu'un long discours, considérant ce qui suit :
Code : Sélectionner tout
var g1 = parent.child.child.child;
Si un des child contient la valeur Null, une exception sera levée :
Code : Sélectionner tout
var g1 = [parent].[child].[null].child;

L'utilisation du nouvel opérateur permet d'assigner la valeur Null à la variable, dans le cas où une des références vaut Null :
Code : Sélectionner tout
1
2
var g1 = parent?.child?.child?.child;
if (g1 != null) // TODO
Au lieu d'un long code équivalent :
Code : Sélectionner tout
1
2
3
4
5
var item = this.Parent;
item = (item == null) ? null : item.child;
item = (item == null) ? null : item.child;
var g1 = (parent == null) ? null : item.child;
if (g1 != null) // TODO
Enfin Mads Torgersen, le manager du projet C# a révélé que même si cet opérateur a reçu les faveurs de la communauté, son introduction était sur les rails depuis plusieurs mois, vu son utilité, sa facilité d'utilisation. Reste à savoir donc la date de sortie de la prochaine version du langage incluant cet opérateur.

Source : Annonce sur MSDN

Et vous ?
Qu’en pensez-vous ?
Pensez-vous que cet opérateur sera introduit prochainement dans d'autres langages ?

Une erreur dans cette actualité ? Signalez-le nous !

Avatar de tomlev
Rédacteur/Modérateur https://www.developpez.com
Le 05/03/2014 à 10:27
Citation Envoyé par Derf59 Voir le message
et qu'on imagine fonctionnellement que la valeur [null] est une valeur possible de child3 mais une valeur qui ne devrait pas arriver sur les parent/child1/child2,
ce type d'affectation masque complétement le problème.
Je ne vois pas où est le problème. Si tu as besoin de savoir si c'est child3 en particulier qui est null, tu peux toujours le tester explicitement, mais il y a énormément de cas où on s'en fout, et où on veut juste la valeur de parent.child1.child2.child3 si elle est disponible, ou null à défaut.

Évidemment ça ne couvre pas la totalité des cas d'utilisation, mais il y a plein de scénarios où ça va rendre le code plus concis et plus lisible. Perso je suis complètement en faveur de cette fonctionnalité.
4  0 
Avatar de tomlev
Rédacteur/Modérateur https://www.developpez.com
Le 05/03/2014 à 10:46
Citation Envoyé par Derf59 Voir le message
et qu'on obtient une valeur null dans g1, on ne sait pas dire d'où elle provient (parent ? child1 ? child2 ? child3 ?) et que si on considère que dans les spécifications fonctionnelles ni parent/child1/child2 ne devraient retourner une valeur "null", on est là face à un "problème qui est complétement masqué".
Si parent, child1 et child2 ne doivent pas être null, alors il suffit de ne pas utiliser l'opérateur "?." pour y accéder... Le but n'est pas de remplacer l'opérateur ".", seulement de le compléter pour les cas où ça a un sens.
4  0 
Avatar de DeVaK
Membre habitué https://www.developpez.com
Le 05/03/2014 à 12:25
Je trouve ça très pratique personnellement, et ce parce que je suis confronté à ce problème de if(chose.truc != null) taratata... C'est juste ultra lourd.

Je suis actuellement sur un Intranet Asp.Net avec EF. Dans mon EF j'ai plusieurs clé étrangère qui peuvent être Null pour une personne. Donc souvent dans mon affichage je tente de faire ça :

Code : Sélectionner tout
View.nom = Chose.Personne.nom;
Seulement pour accéder à nom, il faut que la propriété de navigation soit pas Null, sinon Exception dont je me fou totalement.

Du coup je serais ravi de pouvoir faire un simple :

Code : Sélectionner tout
View.nom = Chose?.Personne.nom;
4  0 
Avatar de DonQuiche
Expert confirmé https://www.developpez.com
Le 05/03/2014 à 18:47
Citation Envoyé par OsoNet Voir le message
Pour moi c'est une solution bancal pour un problème mal identifié.
D'un côté je trouve le fond de ton commentaire pertinent, de l'autre je trouve sa formulation beaucoup trop légère.

* A l'époque où Java et C# ont été introduits ils ajoutaient déjà beaucoup d'innovations. Difficile de leur reprocher de ne pas avoir été encore plus loin.

* Le problème est loin d'être trivial (contrairement à l'impression que tu donnes) et je parie qu'un tel système de types n'est pas accompli sans compromis. Notamment je n'ai jamais travaillé avec un langage incluant l'information de nullité dans le système de types mais cela pose tout un tas de problèmes à résoudre, du marshalling jusqu'aux tableaux. J'aimerais en faire l'expérience mais je me demande si c'est vraiment appréciable au quotidien. Car toutes les initialisations par simple mise à zéro doivent être prohibées pour les types non-nullables et donc tout doit être explicite, ce qui peut peut-être devenir fastidieux. Peut-être pas plus que les tests de nullité en série, certes, mais pas forcément moins non plus.

A priori ça m'a toujours semblé être une bonne idée. Mais de là à prendre les choses de haut à base de "y a qu'à"...
3  0 
Avatar de Thorna
Membre éprouvé https://www.developpez.com
Le 05/03/2014 à 11:51
Bonne idée peut-être, mais pas forcément dans le domaine de la réduction du nombre de lignes de tests dans le code : si le résultat est null, selon le programme ça peut être une réponse tout à fait acceptable, mais ça peut être aussi le signe d'une problème quelque part qui va demander ensuite de tester à quel niveau il s'est produit... Et dans ce cas l'écriture classique avec la série de tests sera sans doute préférable. A moins qu'il y ait un (infime) gain de performance à n'écrire qu'une seule ligne avec des ?. dans le cas où la valeur null est rarissime : la série de tests "après coup" ne sera jouée que très rarement.

Citation Envoyé par Arsene Newman Voir le message
[...] après que cette suggestion est perçue plus de 4.313 votes favorables. [...]
"On a" perçu quelque chose (auxiliaire avoir), pas "on est", et donc on écrit : que cette suggestion ait perçu (ou ait reçu).
Et l'Académie dit que après "après que", on doit utiliser l'indicatif : "après que cette suggestion a perçu".
2  0 
Avatar de tomlev
Rédacteur/Modérateur https://www.developpez.com
Le 05/03/2014 à 14:34
Citation Envoyé par Derf59 Voir le message
Membre en C# ca se limite à attributs d'une classe ou ca comprend aussi les méthodes de cette classe ?
Les membres d'une classe sont les méthodes, propriétés, évènements, champs et constructeurs

(quoi qu'en l'occurrence cet opérateur n'aurait pas beaucoup de sens pour des évènements ou constructeurs bien sûr...)
1  0 
Avatar de Beowulf59
Membre actif https://www.developpez.com
Le 05/03/2014 à 10:22
@Derf59 :

Dans ce cas là l'opérateur n'a pas de raison d'être, vu qu'on ne fait pas child3.child...
Mais si en revanche la valeur null est possible en child2 est pas en child1, rien n'empêche de l'écrire sous la forme :
var g1 = parent.child1.child2?.child3;

Non ? A moins que j'ai mal compris ce point là.

De mon point de vue c'est un opérateur très pratique, mais qu'il faudra utiliser avec parcimonie.
0  0 
Avatar de DelphiManiac
Membre émérite https://www.developpez.com
Le 05/03/2014 à 10:28
Je trouve l'idée très intéressante.

Par contre je ne comprend pas cette remarque
Citation Envoyé par Beowulf59 Voir le message
De mon point de vue c'est un opérateur très pratique, mais qu'il faudra utiliser avec parcimonie.
Soit l'opérateur est adapté au besoin et je ne vois pas pourquoi on ne l'utiliserais pas, soit il n'est pas adapté et la question de son utilisation ne se pose pas. Je ne comprend pas en quoi il faudrait être "parcimonieux".
0  0 
Avatar de pokap
Membre du Club https://www.developpez.com
Le 05/03/2014 à 10:34
C'est un opérateur intéressant mais à double tranchant.
Ça évite d'avoir plusieurs tests à écrire par des if, ce qui alourdi la lecture du code, donc ça reste pour des besoins précis, il y aurait peu de cas d'utilisation.

Par contre avec un tel opérateur on serait tenté de l'utiliser partout alors que ça cacherait des erreurs, ou provoquerait des ralentissements.

Pour moi c'est un opérateur pour un développeur averti qui connait très bien le language et les enjeux du code.
0  0 
Avatar de stailer
Membre chevronné https://www.developpez.com
Le 05/03/2014 à 10:37
Je trouve ça assez pratique... Même sans partir sur 3 ou 4 niveaux, si déjà je peux faire ça :

Code : Sélectionner tout
1
2
MonObjetNull?.MaPropriété
C'est carrément pratique ! fini les "if" classiques ou "en ligne".
Pour la lecture du code c'est bien plus clair.

A chacun de l'utiliser raisonnablement. Il y a déjà bien d'autres façons de produire du code pourri.

Si les équipes C# ne doivent plus rien proposer au risque que le programmeur ne soit pas raisonnable, plus aucune évolution n'est alors possible sur le langage.
0  0