J'ai remarqué que Resharper suggère que je tourne ceci:
if (myObj.myProp is MyType)
{
...
}
dans ceci:
var myObjRef = myObj.myProp as MyType;
if (myObjRef != null)
{
...
}
Pourquoi suggérerait-il ce changement? J'ai l'habitude de Resharper suggérant des changements d'optimisation et des changements de réduction de code, mais j'ai l'impression qu'il veut prendre ma seule déclaration et la transformer en deux lignes.
Selon MSDN :
Une expression is prend la valeur true si les deux conditions suivantes sont remplies:
expression n'est pas nulle. l'expression peut être convertie en type . Autrement dit, une expression transtypée du formulaire
(type)(expression)
se terminera sans lever d'exception.
Suis-je mal interprété cela, ou ne is
fais-je pas exactement les mêmes vérifications, juste en une seule ligne sans avoir besoin de créer explicitement une autre variable locale pour la vérification nulle?
MyProp
getter après ce changement.Réponses:
Parce qu'il n'y a qu'un seul casting. Comparez ceci:
pour ça:
C # 7.0 prend en charge une syntaxe plus compacte utilisant la correspondance de modèles :
la source
as
peut être quelques nanosecondes plus rapide, mais je considère cela comme une microoptimisation prématurée.myObj
oumyProp
pourrait être modifiée (par un autre thread) entre leis
et le cast, provoquant un comportement indésirable.as
+!= null
exécutera également l'!=
opérateur surchargé deMyType
if défini (même s'ilmyObjRef
est nul). Bien que dans la plupart des cas ce ne soit pas un problème (en particulier si vous l'implémentez correctement), dans certains cas extrêmes (mauvais code, performances), cela peut ne pas être souhaité. (devrait être assez extrême cependant)object.ReferenceEquals(null, myObjRef)
.La meilleure option est d'utiliser la correspondance de motifs comme celle-ci:
la source
Il n'y a pas encore d'informations sur ce qui se passe réellement sous la ceinture. Jetez un œil à cet exemple:
Cela se traduit par l'IL suivante:
Ce qui compte ici, ce sont les appels
isinst
etcastclass
- tous deux relativement chers. Si vous comparez cela à l'alternative, vous pouvez voir que cela ne fait qu'uneisinst
vérification:Il convient également de mentionner qu'un type valeur utilisera
unbox.any
plutôt quecastclass
:Notez cependant que cela ne se traduit pas nécessairement par un résultat plus rapide comme nous pouvons le voir ici . Il semble y avoir eu des améliorations depuis cette question a été posée si: moulages semblent être effectuées aussi vite qu'ils l' habitude d'être , mais
as
etlinq
sont maintenant environ 3 fois plus rapide.la source
Avertissement de réaffûtage:
"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 plus. Dans mon cas, j'ignore simplement cet avertissement:
Dans mon code, la deuxième manière est plus longue et moins performante.
la source
IRunable
. Si vous n'avez pas le contrôle, vous pourriez peut-être utiliserdynamic
?Pour moi, cela semble dépendre des chances que ce soit de ce type ou non. Il serait certainement plus efficace de faire le casting à l'avant si l'objet est de ce type la plupart du temps. Si ce n'est qu'occasionnellement de ce type, il peut être plus optimal de vérifier d'abord avec is.
Le coût de création d'une variable locale est très négligeable par rapport au coût du contrôle de type.
La lisibilité et la portée sont généralement les facteurs les plus importants pour moi. Je ne serais pas d'accord avec ReSharper et utiliserais l'opérateur "is" pour cette seule raison; optimisez plus tard s'il s'agit d'un véritable goulot d'étranglement.
(Je suppose que vous n'utilisez
myObj.myProp is MyType
qu'une seule fois dans cette fonction)la source
Cela devrait également suggérer un deuxième changement:
dans
Cela enregistre un accès à la propriété et une distribution, par rapport au code d'origine. Mais ce n'est possible qu'après le passage
is
àas
.la source
(MyType)
lèvera une exception si la conversion échoue.as
ne retourne quenull
.is
(ce code est dans la question).Je dirais que c'est pour créer une version fortement typée de myObj.myProp, qui est myObjRef. Cela doit ensuite être utilisé lorsque vous faites référence à cette valeur dans le bloc, plutôt que de devoir effectuer un cast.
Par exemple, ceci:
c'est mieux que ça:
la source