web-dev-qa-db-fra.com

Le recours à && est-il sécurisé dans .NET?

Supposons que myObj est null. Est-il prudent d'écrire ceci?

if(myObj != null && myObj.SomeString != null)

Je sais que certaines langues n'exécutent pas la seconde expression car le && est évalué à false avant l'exécution de la seconde partie.

44
datatoad

Oui. En C #, && et || sont en court-circuit et évaluent donc le côté droit uniquement si le côté gauche ne détermine pas déjà le résultat. Les opérateurs & et | en revanche ne court-circuitent pas et évaluent toujours les deux côtés.

La spécification dit:

Les opérateurs && et || sont appelés opérateurs logiques conditionnels. Ils sont également appelés opérateurs logiques «court-circuit».
...
L'opération x && y correspond à l'opération x & y, sauf que y est évalué uniquement si x est true
...
L'opération x && y est évaluée en tant que (bool)x ? (bool)y : false. En d'autres termes, x est d'abord évalué et converti au type bool. Ensuite, si x est true, y est évalué et converti au type bool, et cela devient le résultat de l'opération. Sinon, le résultat de l'opération est false.

(Spécification du langage C #, versions 4.0 à 7.12, opérateurs logiques conditionnels)

Une propriété intéressante de && et || est qu’ils court-circuitent même s’ils ne fonctionnent pas sur des bools, mais sur des types pour lesquels l’utilisateur a surchargé les opérateurs & ou | avec les opérateurs true et false.

L'opération x && y est évaluée en tant que T.false((T)x) ? (T)x : T.&((T)x, y), où T.false((T)x) est une invocation du operator false déclaré dans T, et T.&((T)x, y) est une invocation du operator & sélectionné. De plus, la valeur (T) x ne doit être évaluée qu'une fois.

En d'autres termes, x est d'abord évalué et converti au type T et operator false est appelé sur le résultat pour déterminer si x est définitivement false.
Ensuite, si x est définitivement false, le résultat de l'opération est la valeur précédemment calculée pour x convertie en type T.
Sinon, y est évalué et l'opérateur sélectionné & est invoqué sur la valeur précédemment calculée pour x convertie en type T et la valeur calculée pour y pour générer le résultat de l'opération.

(Spécification du langage C #, versions 4.0 à 7.12.2 Opérateurs logiques conditionnels définis par l'utilisateur)

70
CodesInChaos

Oui, C # utilise un court-circuit logique.

Notez que bien que C # (et quelques autres langages .NET) se comportent de cette manière, il s'agit d'une propriété du langage, pas du CLR.

14
harpo

Je sais que je suis en retard à la fête, mais en C # 6.0, vous pouvez le faire aussi:

if(myObj?.SomeString != null)

Qui est la même chose que ci-dessus.

Voir aussi: Qu'est-ce qu'un point d'interrogation et un opérateur de points?. signifie en C # 6.0?

7
Drew Delano

Votre code est sécurisé - && et || sont tous deux court-circuités. Vous pouvez utiliser des opérateurs & ou |, non court-circuités, qui évaluent les deux extrémités, mais je ne le vois vraiment pas dans beaucoup de code de production.

4
Joe Enos

bien sûr, c'est sûr en C #, si le premier opérande est faux, le second n'est jamais évalué.

3
Mauricio

un exemple est

if(strString != null && strString.Length > 0)

Cette ligne provoquerait une exception nulle si les deux côtés étaient exécutés.

Note latérale intéressante. L'exemple ci-dessus est un peu plus rapide que la méthode IsNullorEmpty.

1
Bengie

En C #, && et || sont court-circuités, ce qui signifie que la première condition est évaluée et que le reste est ignoré si la réponse est déterminée.

Dans VB.NET, AndAlso et OrElse sont également court-circuités.

En javaScript, && et || sont également court-circuités.

Je mentionne VB.NET pour montrer que le vilain beau-fils roux de .net a aussi des trucs sympas aussi, parfois.

Je parle de javaScript, car si vous faites du développement Web, vous pourriez probablement aussi utiliser javaScript.

0
John Grabauskas

C'est parfaitement sécuritaire. C # est l'une de ces langues.

0
Ilya Kogan

Oui, C # et la plupart des langues calculent les phrases if de gauche à droite.

VB6, en passant, calculera le tout, et lèvera une exception si elle est nulle ...

0
Yochai Timmer