2008-12-17 8 views
7

Imaginez ce cas où j'ai un objet dont j'ai besoin pour vérifier une propriété. Toutefois, l'objet peut actuellement avoir une valeur nulle.Structure chaînée IF

Comment puis-je vérifier ces deux conditions dans une seule condition "si"?

Actuellement, je dois faire quelque chose comme ceci:

if (myObject != null) 
{ 
    if (myObject.Id != pId) 
    { 
     myObject.Id = pId; 
     myObject.Order = pOrder; 
    } 
} 

Je voudrais quelque chose comme ceci:

if (myObject != null && myObject.Id != pId) 

Je veux évaluer la deuxième condition que si le premier était vrai.

Peut-être que je manque quelque chose, et c'est la raison pour laquelle j'ai besoin de votre aide ;-)

+0

Pourquoi 'if (myObject! = Null && myObject.Id! = PId)' lance-t-il une exception? Je pense que c'est exactement ce que tu veux! –

+0

@Carlos Maintenant c'est corrigé. –

Répondre

43
if(myObject != null && myObject.Id != pId) 
{ 
    myObject.Id = pId; 
    myObject.Order = pOrder; 
} 

&& est un test logique court-circuit - il n'évalue le droit côté gauche si la le côté main est vrai. Contraste à « un & b », qui évalue toujours les deux côtés (et ne Bitwise « et »)

+0

Ok, mais je ne veux pas jeter d'exception. Je voulais seulement que la deuxième condition soit évaluée si la première était vraie. –

+0

Actualiser la page ;-p –

+0

Nelson, le code fait exactement cela. Si myObject est null, la partie droite du if ne sera jamais évaluée. –

5
if (myObject != null && myObject.Id != pId) 
{ 
//bla 
} 

c'est sûr parce que l'opérateur & & est évalué paresseusement, ce qui signifie que si le LHS est faux, l'ERS est jamais évalué

+0

Je peux dire que j'ai déjà appris quelque chose aujourd'hui. Merci. –

1
if (myObject != null && myObject.Id != pId) 
{ 
    myObject.Id = pId; 
    myObject.Order = pOrder; 
} 
4

Ce code va d'abord vérifier si myObject est non nul, dans le cas qui est vrai, il vérifiera la condition suivante, dans le cas qui n'est pas vrai, il ne vérifie pas la condition suivante et non exécuter le code.

if (myObject != null && myObject.Id != pId) 
{ 
    myObject.Id = pId; 
    myObject.Order = pOrder; 
} 
3

Vous avez beaucoup de bonnes réponses sur la façon de le faire. Je veux juste mettre en garde sur la façon de ne pas le faire. N'enveloppez pas le test unique pour id = pid dans un bloc try-catch. C'est gaspillage et impliquerait l'introduction de la vérification d'exception pour attraper une condition non-exceptionnelle. C'est une si mauvaise idée que je ne vais même pas l'illustrer par un exemple.

+0

Oui, vous avez raison. Je ne ferais pas ça, de toute façon. D'abord je vérifierais la valeur nulle dans myObject. –

10

Il convient de souligner que l'évaluation court-circuité du & & dans le cas() est absolument garanti par les normes linguistiques (C, C++, Java et C#). Il en est ainsi depuis la première édition de K & R "C Langage de programmation".

Ce n'est pas quelque chose que vous devez vous inquiéter "Est-ce que mon compilateur l'implémente?". Si certainement fait.

+0

Merci, je ne connaissais pas cette chose d'évaluation en court-circuit. Semble un peu boiteux maintenant, mais c'est la vérité. –

+0

C'est quelque chose * beaucoup * de personnes ne connaissent pas! Et beaucoup qui trébuchent dessus, pensent que c'est une bizarrerie compilateur. –

1
if(!(myObject == null || myObject.Id == pId)) 
{ 
    myObject.Id = pId; 
    myObject.Order = pOrder; 
} 
1

Je pense que dans VB.net vous pouvez utiliser le mot-clé andAlso comme alternative à ce comportement. Donc, quelque chose comme ...

if(myObject != null andAlso myObject.Id != pId) 
    { 
    myObject.Id = pId; 
    myObject.Order = pOrder; 
    } 

fait exactement la même chose que je pense, mais il est là comme une alternative!

Édition: modification de C# en VB.net ci-dessus

+0

C# n'a pas le mot clé andAlso.Bien que, VB l'a, et c'est ce que j'ai rappelé, depuis que j'ai commencé .NET avec VB. Mais la réponse est && opérateur. –

+0

Oups! Toutes mes excuses pour cela. Edited post pour refléter ce fait – chillysapien

1

Depuis je pense que cela peut être utile aux autres personnes qui regardent cette question à l'avenir. Comme indiqué, l'utilisation de & & fournit la fonctionnalité souhaitée. Mais, il convient également de noter, la fonctionnalité que vous aviez peur, que les deux parties seraient évaluées indépendamment du résultat de la première évaluation peut être obtenu en utilisant & au lieu de & &. Donc:

//DO NOT USE THIS CODE 
//this will throw an exception if myObject is null 
//because myOject.Id != pId will still be evaluated 
if(myObject != null & myObject.Id != pId) 
{ 
    myObject.Id = pId; 
    myObject.Order = pOrder; 
} 

Encore une fois, pour cet exemple, vous ne voulez pas ce code. Je voulais simplement l'ajouter à la conversation car il peut y avoir des cas (même si je ne l'ai jamais trouvé un) lorsque cela est la fonctionnalité que vous voulez, par exemple:

//always run both methods 
if(MethodA() & MethodB()) 
{ 
    //do stuff only when both methods return true 
} 
+0

Bonne contribution. Merci. –

1

Vous pouvez utiliser & pour évaluer deux conditions, mais si vous voulez tester la seconde seulement si le premier élément est vrai, vous pouvez utiliser & &.

En portugais, nous appelons ceci: "AND com curto circuito".

if (myObject != null && myObject.Id != pId) 

si myObject est faux, vous ne pouvez pas tester myObject.Id car myObject est nul et vous ne pouvez pas accéder à une propriété d'un objet nul.

:::::::::::::::::::::::

aba & & b

true true true

true false false

faux vrai faux

false false false

:::::::::::::::::::