2016-06-08 3 views
3

У меня есть следующий код:Почему C# проверяет, имеет ли значение 'var' значение null?

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

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

    } 
} 

Как это можно проверить varСообщи против null? Что говорит компилятору, что var - это IMessage, а не int или какой-либо другой тип, который не может быть обнулен?

Если вы посмотрите на пример выше на MSDN, они дают неявно введенные переменные начальные значения (при этом объявление становится явным). В моем случае я даже не придаю ему значения, но у компилятора нет проблем с ним. Как компилятор знает, что msg имеет значение NULL?

+6

Ваш 'messageList' - это список элементов типа' IMessage', поэтому компилятор может легко определить, что фактический тип 'msg' -' IMessage'. Если компилятор не мог вывести тип, вы не сможете использовать 'var' - например. 'var msg;' не будет разрешено. – stuartd

+0

В любом случае сравнение значения с 'null' всегда допустимо. Компилятор просто выдает предупреждение, если 'msg' был' int', так как сравнение всегда 'true', но это не было бы запрещено. –

+0

@JeroenMostert Когда я проверяю «null» на тип значения, я получаю больше, чем предупреждение. Не уверен, что вы говорите. – Snoopy

ответ

4

Компилятор знает, что msg является нулевым, потому что он статически типизирован. Статический тип - IMessage, даже если вы его не назвали.

Причина компилятор замещенного IMessage для var является то, что оно появилось в foreach (varidentifierincollection) и collection является выражением такого типа, который реализует IEnumerable<IMessage>.

При каждом появлении var будет установлен статический тип. (Возможно, это должно быть dynamic, но dynamic не является значением по умолчанию, оно может применяться только тогда, когда оно может быть определено в соответствии с правилами ввода статического типа). Если правила вывода статического типа не могут найти уникальный тип для замены, то это использование var запрещено.

0

Компилятор описывает тип для вас. На базовом уровне, когда вы говорите:

var x = "foo"; 

Компилятор видит, что правая часть выражения является x, что тип string и правопреемников.

Это не так, когда компилятор встречается с оператором foreach. Он определяет тип IEnumerable (IEnumerable<IMessage> в вашем случае) и присваивает msg тип IMessage.

0

В вашем примере, ваш messageList имеет тип List<IMessage>, поэтому, когда вы делаете

foreach (var m in messageList)

C# автоматически знать, какой тип элементов ожидать (те, содержащиеся в списке, в этом примере IMessage объекты) и сообщает, что var будет переведен в IMessage во время компиляции.

Ключевое слово var - это просто синтаксический сахар, на самом деле это не тип. Это просто делает вашу жизнь проще (вам не нужно писать фактический тип)

0

Тип varвсегда известный во время компиляции. Любая ситуация, когда тип не может быть выведен из синтаксиса, будет ошибкой времени компиляции.

В этом случае вы выполняете итерирование по типизированной коллекции IMessage s, поэтому компилятор знает, что переменная итерации имеет тип IMessage и поэтому имеет значение NULL.

1

var - очень вводящее в заблуждение ключевое слово.
var объявляет переменную с определенным типом данных, , не сообщив программисту, что это за тип.

То, что вы на самом деле объявили это

foreach (IMessage msg in messageList) 

но вы должны работать, что для себя.

Смежные вопросы