Mir ist aufgefallen, dass Resharper vorschlägt, dies zu ändern:
if (myObj.myProp is MyType)
{
...
}
das mögen:
var myObjRef = myObj.myProp as MyType;
if (myObjRef != null)
{
...
}
Warum sollte es diese Änderung vorschlagen? Ich bin es gewohnt, mit Resharper Optimierungs- und Code-Reduktionsänderungen vorzuschlagen, aber es scheint, als würde ich meine einzelne Anweisung in einen Zweiliner umwandeln wollen.
Laut MSDN :
Ein is- Ausdruck wird als wahr ausgewertet, wenn beide der folgenden Bedingungen erfüllt sind:
Ausdruck ist nicht null. Ausdruck kann in Typ umgewandelt werden . Das heißt, ein Besetzungsausdruck des Formulars
(type)(expression)
wird ohne Ausnahme abgeschlossen.
Verstehe ich das falsch oder mache nicht is
genau die gleichen Prüfungen nur in einer einzigen Zeile, ohne dass explizit eine andere lokale Variable für die Nullprüfung erstellt werden muss?
MyProp
Getter nach dieser Änderung nicht brauchen .Antworten:
Weil es nur eine Besetzung gibt. Vergleichen Sie dies:
dazu:
C # 7.0 unterstützt eine kompaktere Syntax mit Pattern Matching :
quelle
as
mag ein paar Nanosekunden schneller sein, aber ich halte dies für eine vorzeitige Mikrooptimierung.myObj
odermyProp
könnte (durch einen anderen Thread) zwischen demis
und dem Cast geändert werden , was zu unerwünschtem Verhalten führt.as
+!= null
auch den überschriebenen!=
Operator vonMyType
if ausführt (auch wenn ermyObjRef
null ist). Während dies in den meisten Fällen kein Problem darstellt (insbesondere wenn Sie es ordnungsgemäß implementieren), ist es in einigen extremen Fällen (schlechter Code, Leistung) möglicherweise nicht erwünscht. (müsste allerdings ziemlich extrem sein )object.ReferenceEquals(null, myObjRef)
.Die beste Option ist die Verwendung eines solchen Mustervergleichs:
quelle
Es gibt noch keine Informationen darüber, was tatsächlich unter der Gürtellinie passiert. Schauen Sie sich dieses Beispiel an:
Dies führt zu folgender IL:
Was hier zählt, sind die
isinst
undcastclass
Anrufe - beide relativ teuer. Wenn Sie das mit der Alternative vergleichen, sehen Sie, dass nur eineisinst
Überprüfung durchgeführt wird:Erwähnenswert ist auch, dass ein Werttyp
unbox.any
eher Folgendes verwendet alscastclass
:Beachten Sie jedoch, dass dies nicht unbedingt zu einem schnelleren Ergebnis führt, wie wir hier sehen können . Es scheint Verbesserungen gewesen zu sein , da diese Frage gestellt wurde , obwohl: Abgüsse scheinen so schnell durchgeführt werden , wie sie verwendet werden , aber
as
undlinq
sind jetzt etwa 3 - mal schneller.quelle
Warnung zum Nachschärfen:
"Type check and direct cast can be replaced with try cast and check for null"
Beides wird funktionieren, es hängt davon ab, wie Ihr Code besser zu Ihnen passt. In meinem Fall ignoriere ich diese Warnung einfach:
In meinem Code ist der 2. Weg länger und die Leistung schlechter.
quelle
IRunable
. Wenn Sie nicht die Kontrolle haben, könnten Sie vielleicht verwendendynamic
?Für mich scheint dies davon abhängig zu sein, wie hoch die Wahrscheinlichkeit ist, dass es von diesem Typ sein wird oder nicht. Es wäre sicherlich effizienter, die Besetzung im Voraus durchzuführen, wenn das Objekt die meiste Zeit von diesem Typ ist. Wenn es nur gelegentlich von diesem Typ ist, ist es möglicherweise optimaler, zuerst mit is zu prüfen.
Die Kosten für die Erstellung einer lokalen Variablen sind im Vergleich zu den Kosten für die Typprüfung sehr vernachlässigbar.
Lesbarkeit und Umfang sind für mich in der Regel die wichtigsten Faktoren. Ich würde ReSharper nicht zustimmen und den Operator "is" allein aus diesem Grund verwenden. Optimieren Sie später, wenn dies ein echter Engpass ist.
(Ich gehe davon aus, dass Sie
myObj.myProp is MyType
in dieser Funktion nur einmal verwenden)quelle
Es sollte auch eine zweite Änderung vorschlagen:
in
Dies spart einen Eigenschaftszugriff und eine Besetzung im Vergleich zum ursprünglichen Code. Dies ist jedoch erst nach dem Wechsel
is
zu möglichas
.quelle
(MyType)
wird werfen Ausnahme , wenn die Umwandlung fehlschlägt.as
kehrt nur zurücknull
.is
(dieser Code ist in Frage).Ich würde sagen, dies ist eine stark typisierte Version von myObj.myProp, nämlich myObjRef. Dies sollte dann verwendet werden, wenn Sie auf diesen Wert im Block verweisen, anstatt einen Cast durchführen zu müssen.
Zum Beispiel:
ist besser als das:
quelle