2016-11-29 4 views
0

Wird das folgende Verhalten erwartet?Reihenfolge der Auswertung bei Verwendung des bedingten Operators

public class TestClass 
{ 
    public int IntValue { get; set; } 
} 

TestClass instance = null; 

// this line throws exception: Object reference not set to an instance of an object 
string test1 = "abc" + instance != null ? instance.IntValue.ToString() : "0"; 

// this works 
string test2 = instance != null ? instance.IntValue.ToString() : "0"; 

// this works 
string test3 = "abc" + (instance != null ? instance.IntValue.ToString() : "0"); 

UPDATE:

Wie kommt dies keine Ausnahme werfen?

TestClass instance = null; 
string test4 = "abc" + instance; 
string test5 = "abc" + true; 
+13

Ja, es ist zu erwarten. – JLRishe

+4

'" abc "+ instance' ist nie null – fubo

+1

In dem Moment, in dem Sie versuchen," abc "und die Instanz zu verketten, wird ToString() für Instanz aufgerufen - wenn dies null ist, erhalten Sie die Ausnahme, also ja, wird erwartet. – Darren

Antwort

10

Ihr Problem ist die Vorrangstellung des Bedieners. + rangiert höher als !=und?:. Ihre Linie, die nicht funktioniert auch wie folgt geschrieben werden:

string test1 = ("abc" + instance) != null ? instance.IntValue.ToString() : "0"; 

Der Ausdruck "abc" + instance ist nienull, auch wenn instance ist null. Das bedeutet, dass Ihr Ausdruck immer true ist, was Sie auf NullReferenceException im Ausdruck Ausdruck in dem Fall instance ist null.

Sie können die Vorrangstellung des Operators mit Parenthisierung überschreiben. Das bedeutet, dass Sie sicher, dass instance != null ? instance.IntValue.ToString() zuerst ausgewertet machen müssten, indem sie sie in runden Klammern:

string test1 = "abc" + (instance != null ? instance.IntValue.ToString() : "0"); 

UPDATE:

Soweit Ihre Fragen in dem Update betrifft: Diese Ausdrücke nicht werfen einen Fehler, weil es an einer Schnur zwei Besonderheiten über die + Betreiber Implementierung sind:

  1. Es ist tolerant gegenüber null Werte, solange Sie eine gültige st haben klingeln auf der anderen Seite.
  2. Da die ToString Verfahren in System.Object implementiert ist, jeder Wert mit ToString in einen String umgewandelt werden. Daher ist es möglich, einem String Zeichenketten ohne String hinzuzufügen (nur auf der rechten Seite).
+0

Ich verstehe dieses Gruppierungsproblem, ich bin nur überrascht, dass es keine Compiler-Warnung gibt, wie "Warnung, Ausdruck kann nie null sein" oder Worte zu diesem Zweck. – Joe

+0

Der Compiler könnte Sie wahrscheinlich vor diesem speziellen Fall warnen, aber er kann Sie nicht generell warnen, da das '+' überladen werden kann und daher der Compiler nicht immer weiß, dass der Ausdruck 'null' ergibt. – Sefe

+1

@Joe Resharper fängt es auf. – juharr

2

Ja. Es ist. Dies liegt daran, dass die "abc" + instance zuerst ausgewertet wird. Dann prüft es, ob es Null ist (was offensichtlich nicht wahr sein kann). Dann im true Pfad versucht es, den Wert instance zu erhalten, der null ist und daher diese Ausnahme gibt.

Die Reihenfolge der Auswertung wird innerhalb der Sprache festgelegt, die angibt, dass + is being handled before !=.

Verwandte Themen