Ist es möglich, diese Aussage irgendwie zu verkürzen?
if (obj != null)
obj.SomeMethod();
weil ich das zufällig viel schreibe und es ziemlich nervig wird. Das einzige, woran ich denken kann, ist die Implementierung eines Null-Objekt- Musters, aber das kann ich nicht jedes Mal tun, und es ist sicherlich keine Lösung, um die Syntax zu verkürzen.
Und ähnliches Problem mit Ereignissen, wo
public event Func<string> MyEvent;
und dann aufrufen
if (MyEvent != null)
MyEvent.Invoke();
Antworten:
Ab C # 6 können Sie einfach Folgendes verwenden:
oder:
Das
?.
ist der sich null ausbreitende Operator und bewirkt, dass der Operator.Invoke()
kurzgeschlossen wird, wenn der Operand istnull
. Auf den Operanden wird nur einmal zugegriffen, sodass kein Risiko für das Problem "Wertänderungen zwischen Prüfung und Aufruf" besteht.===
Vor C # 6 nein: Es gibt keine null-sichere Magie, mit einer Ausnahme; Erweiterungsmethoden - zum Beispiel:
jetzt ist dies gültig:
Bei Ereignissen hat dies den Vorteil, dass auch die Race-Bedingung entfernt wird, dh Sie benötigen keine temporäre Variable. Normalerweise benötigen Sie also:
aber mit:
wir können einfach verwenden:
quelle
?.
- in VB14 und höherWas Sie suchen, ist der Operator Null Conditional (nicht "Coalescing") :
?.
. Es ist ab C # 6 verfügbar.Ihr Beispiel wäre
obj?.SomeMethod();
. Wenn obj null ist, passiert nichts. Wenn die Methode Argumente enthält, werdenobj?.SomeMethod(new Foo(), GetBar());
die Argumente beispielsweise nicht ausgewertet, wenn sieobj
null sind. Dies ist wichtig, wenn die Auswertung der Argumente Nebenwirkungen hätte.Und Verkettung ist möglich:
myObject?.Items?[0]?.DoSomething()
quelle
Eine schnelle Erweiterungsmethode:
Beispiel:
oder alternativ:
Beispiel:
quelle
Ereignisse können mit einem leeren Standarddelegaten initialisiert werden, der niemals entfernt wird:
Keine Nullprüfung erforderlich.
[ Update , danke an Bevan für den Hinweis]
Beachten Sie jedoch die möglichen Auswirkungen auf die Leistung. Ein schneller Mikro-Benchmark, den ich durchgeführt habe, zeigt an, dass die Behandlung eines Ereignisses ohne Abonnenten 2-3-mal langsamer ist, wenn das Muster "Standarddelegierter" verwendet wird. (Auf meinem 2,5-GHz-Dual-Core-Laptop bedeutet dies 279 ms: 785 ms, um 50 Millionen nicht abonnierte Ereignisse auszulösen.) Bei Anwendungs-Hotspots kann dies ein zu berücksichtigendes Problem sein.
quelle
Ja, in C # 6.0 - https://msdn.microsoft.com/en-us/magazine/dn802602.aspx .
quelle
Dieser Artikel von Ian Griffiths gibt zwei verschiedene Lösungen für das Problem, von dem er schlussfolgert, dass es nette Tricks sind, die Sie nicht anwenden sollten.
quelle
Die Cerating Extention-Methode, wie sie vorgeschlagen wurde, löst Probleme mit den Rennbedingungen nicht wirklich, sondern verbirgt sie.
Wie bereits erwähnt, ist dieser Code das elegante Äquivalent zur Lösung mit temporärer Variable, aber ...
Das Problem bei beiden ist, dass es möglich ist, dass der Subsciber des Ereignisses aufgerufen wird, nachdem er sich vom Ereignis abgemeldet hat . Dies ist möglich, da die Abmeldung erfolgen kann, nachdem die Delegateninstanz in die temporäre Variable kopiert (oder in der obigen Methode als Parameter übergeben) wurde, jedoch bevor der Delegat aufgerufen wird.
Im Allgemeinen ist das Verhalten des Client-Codes in einem solchen Fall nicht vorhersehbar: Der Komponentenstatus konnte die Ereignisbenachrichtigung nicht bereits verarbeiten. Es ist möglich, Client-Code so zu schreiben, dass er damit umgeht, aber dies würde dem Client unnötige Verantwortung auferlegen.
Die einzige bekannte Möglichkeit, die Thread-Sicherheit zu gewährleisten, ist die Verwendung der Lock-Anweisung für den Absender des Ereignisses. Dadurch wird sichergestellt, dass alle Abonnements \ Abmeldungen \ Aufruf serialisiert werden.
Um genauer zu sein, sollte die Sperre auf dasselbe Synchronisierungsobjekt angewendet werden, das in den Methoden zum Hinzufügen / Entfernen von Ereigniszugriff verwendet wird. Dies ist die Standardeinstellung 'this'.
quelle
Ich stimme der Antwort von Kenny Eliasson zu. Gehen Sie mit Erweiterungsmethoden. Hier finden Sie eine kurze Übersicht über die Erweiterungsmethoden und Ihre erforderliche IfNotNull-Methode.
Erweiterungsmethoden (IfNotNull-Methode)
quelle
Vielleicht nicht besser, aber meiner Meinung nach besser lesbar ist es, eine Erweiterungsmethode zu erstellen
quelle
return obj == null
Mittelwert. Was wird es zurückkehrenobj
istnull
das Verfahren zurückkehrentrue
, glaube ich.null
? Ich bin mir ziemlich sicher, dass dies nicht mit den eigenen Methoden des Typs funktioniert, daher bezweifle ich, dass dies auch mit Erweiterungsmethoden funktionieren würde. Ich glaube, der beste Weg, um zu überprüfen, ob ein Objekt ist,null
istobj is null
. Um zu überprüfen, ob ein Objekt nicht vorhandennull
ist, muss es leider nicht in Klammern gesetzt werden, was unglücklich ist.Dafür gibt es in C # einen wenig bekannten Nulloperator, ??. Kann hilfreich sein:
http://weblogs.asp.net/scottgu/archive/2007/09/20/the-new-c-null-coalescing-operator-and-using-it-with-linq.aspx
quelle