2016-06-08 27 views
3

Ich habe den folgenden Code:Warum kann C# prüfen, ob ein 'var' null ist?

List<IMessage> messageList = new List<IMessage>(); 

foreach(var msg in messageList) 
{ 
    if(msg != null) 
    { 

    } 
} 

Wie ist es möglich, die varmsg gegen null zu überprüfen? Was sagt der Compiler, dass var ist ein IMessage und nicht ein int oder ein anderer Typ, der nicht nullfähig ist?

Wenn Sie das Beispiel über MSDN betrachten, geben sie den implizit typisierten Variablen Anfangswerte (wodurch die Deklaration explizit wird). In meinem Fall gebe ich nicht einmal einen Wert, aber der Compiler hat kein Problem damit. Woher weiß der Compiler, dass die msg Nullable ist?

+6

Ihre 'messageList' ist eine Liste von Elementen vom Typ' IMessage', so dass der Compiler leicht darauf schließen kann, dass der eigentliche Typ von 'msg'' IMessage' ist. Wenn der Compiler den Typ nicht ableiten könnte, wäre es nicht möglich, 'var' zu verwenden - z. 'var msg;' wäre nicht erlaubt. – stuartd

+0

Nebenbei ist der Vergleich eines Wertes gegen "Null" immer zulässig. Der Compiler würde einfach eine Warnung ausgeben, wenn 'msg' ein 'int' wäre, da der Vergleich immer 'wahr' ist, aber nicht erlaubt wäre. –

+0

@JeroenMostert Wenn ich 'null' für einen Werttyp überprüfe, erhalte ich mehr als eine Warnung. Nicht sicher, was du sagst. – Snoopy

Antwort

4

Der Compiler weiß, dass msg Nullable ist, weil es statisch typisiert ist. Der statische Typ ist IMessage, obwohl Sie es nicht benannt haben.

Der Grund der Compiler IMessage für var substituiert ist, dass es identifierincollection) und die collection ist ein Ausdruck eines Typs in foreach (var schien, dass IEnumerable<IMessage> implementiert.

Jedes Auftreten von var wird einige statisch substituiert haben. (Dies ist möglich dynamic, aber dynamic ist kein Standard, es kann nur gelten, wenn es unter den statischen Typ-Inferenzregeln abgeleitet werden kann) Wenn die statischen Typ-Inferenzregeln keinen eindeutigen Typ zum Ersetzen finden können, dann das Verwendung von var ist nicht erlaubt.

0

Der Compiler leitet den Typ für Sie ab. Auf einer grundlegenden Ebene, wenn Sie sagen:

var x = "foo"; 

Der Compiler sieht, dass die rechte Seite des Ausdrucks eine string und Abtretungsempfänger ist x dass Art.

Es ist nicht anders, wenn der Compiler auf eine foreach Anweisung trifft. Er ermittelt den IEnumerable Typ (IEnumerable<IMessage> in Ihrem Fall) und weist msg den Typ IMessage zu.

0

In Ihrem Beispiel Ihre messageList ist vom Typ List<IMessage> daher, wenn Sie

foreach (var m in messageList)

C# automatisch wissen tun, welche Art von Gegenständen zu erwarten (die in der Liste enthalten sind diejenigen, die in diesem Beispiel IMessage Objekte) und folgert, dass die Variable während der Kompilierungszeit in IMessage übersetzt wird.

Das Schlüsselwort var ist nur syntaktischer Zucker, es ist eigentlich kein Typ. Es macht Ihr Leben einfacher (Sie müssen nicht den eigentlichen Typ schreiben)

0

Der Typ eines var ist immer bekannt zur Kompilierzeit. Jede Situation, in der der Typ nicht aus der Syntax abgeleitet werden kann, wäre ein Fehler bei der Kompilierung.

In diesem Fall durchlaufen Sie eine typisierte Auflistung von IMessage s, sodass der Compiler weiß, dass die Iterationsvariable vom Typ IMessage und daher nullfähig ist.

1

var ist ein sehr irreführendes Schlüsselwort.
var deklariert eine Variable mit einem bestimmten Datentyp, , ohne dem Programmierer mitzuteilen, um was für einen Typ es sich handelt.

Was Sie tatsächlich erklärt haben, ist

foreach (IMessage msg in messageList) 

aber man muss das für sich selbst heraus arbeiten.