100 votes

'is' versus try cast avec contrôle nul

J'ai remarqué que Resharper me suggère de transformer ceci:

if (myObj.myProp is MyType)
{
   ...
}

dans ce:

var myObjRef = myObj.myProp as MyType;
if (myObjRef != null)
{
   ...
}

Pourquoi serait-il suggérer ce changement? Je suis habitué à Resharper ce qui suggère l'optimisation des changements de code et de réduction des changements, mais il se sent comme il veut prendre ma seule déclaration et le transformer en un deux-liner.

Selon MSDN:

Une est l'expression renvoie la valeur true si les deux conditions suivantes sont remplies:

l'expression n'est pas nulle. l'expression peut être converti en type. C'est, une fonte d'expression de la forme (type)(expression) sera complète sans lancer une exception.

Suis-je une erreur de lecture, ou n'a pas d' is faire exactement les mêmes vérifications, juste dans une seule ligne, sans avoir besoin de créer explicitement une autre variable locale pour les nuls?

129voto

Jeff E Points 2025

Parce qu'il n'y a qu'un seul casting. Comparez ceci:

 if (myObj.myProp is MyType) // cast #1
{
    var myObjRef = (MyType)myObj.myProp; // needs to be cast a second time
                                         // before using it as a MyType
    ...
}
 

pour ça:

 var myObjRef = myObj.myProp as MyType; // only one cast
if (myObjRef != null)
{
    // myObjRef is already MyType and doesn't need to be cast again
    ...
}
 

4voto

Tom Points 2833

Avertissement Resharper:

"Type check and direct cast can be replaced with try cast and check for null"

Les deux fonctionneront, cela dépend de la façon dont votre code vous convient le mieux. Dans mon cas, j'ignore cet avertissement:

 //1st way is n+1 times of casting
if (x is A) ((A)x).Run();
else if (x is B) ((B)x).Run();
else if (x is C) ((C)x).Run();
else if (x is D) ((D)x).Run();
//...
else if (x is N) ((N)x).Run();    
//...
else if (x is Z) ((Z)x).Run();

//2nd way is z times of casting
var a = x as Type A;
var b = x as Type B;
var c = x as Type C;
//..
var n = x as Type N;
//..
var z = x as Type Z;
if (a != null) a.Run();
elseif (b != null) b.Run();
elseif (c != null) c.Run();
...
elseif (n != null) n.Run();
...
elseif (x != null) x.Run();
 

Dans mon code, la 2ème manière est une performance plus longue et moins bonne.

3voto

Derrick Points 890

Pour moi, cela semble dépendre de ce que les chances sont qu'il va être de ce type ou non. Il serait certainement plus efficace de faire de l'incantation à l'avant si l'objet est de ce type, la plupart du temps. Si c'est seulement à l'occasion de ce type, alors il peut être plus optimale de vérifier d'abord avec est.

Le coût de création d'une variable locale est très négligeable par rapport au coût de la vérification de type.

La lisibilité et la portée sont les facteurs les plus importants pour moi en général. Je ne serais pas d'accord avec ReSharper, et d'utiliser le "est" de l'opérateur pour cette seule raison; optimiser plus tard si c'est un vrai goulot d'étranglement.

(Je suis en supposant que vous êtes seulement en utilisant myObj.myProp is MyType une fois dans cette fonction)

0voto

Ben Voigt Points 151460

Cela devrait aussi suggérer un deuxième changement:

 (MyType)myObj.myProp
 

dans

 myObjRef
 

Cela enregistre un accès à la propriété et une conversion, par rapport au code d'origine. Mais ce n'est possible qu'après avoir changé is en as .

0voto

Jerad Rose Points 5960

Je dirais que cela consiste à créer une version fortement typée de myObj.myProp, qui est myObjRef. Cela devrait alors être utilisé lorsque vous référencez cette valeur dans le bloc, par opposition à une conversion.

Par exemple, ceci:

 myObjRef.SomeProperty
 

c'est mieux que ça:

 ((MyType)myObj.myProp).SomeProperty
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X