Тип возврата условного оператора C # - PullRequest
2 голосов
/ 30 октября 2011

У меня есть объект с именем EmailMessage, который имеет пустое поле System.DateTime с именем Timestamp. В моем коде C # у меня есть следующая строка:

var TS = EmailMessage.Timestamp == null ? System.DateTime.Now : EmailMessage.Timestamp;

Почему .NET 4 выводит тип данных TS как System.DateTime? а не System.DateTime (Другими словами, почему .NET 4 думает, что TS обнуляем?

Заранее спасибо за помощь.

Ответы [ 5 ]

5 голосов
/ 30 октября 2011

Поскольку компилятор C # просто смотрит на типы DateTime.Now и EmailMessage.Timestamp: -)

И я скажу вам кое-что: я могу нарушить ваше предположение. Допустим, есть две темы. Один поток имеет ваш код, другой поток EmailMessage.Timestamp = null. Другой поток выполняется между EmailMessage.Timestamp == null и TS = EmailMessage.Timestamp. Перерыв: -)

Я добавлю, что ваш код обычно пишется так:

var TS = EmailMessage.Timestamp ?? System.DateTime.Now;

с использованием ?? Оператор Таким образом, компилятор знает, что TS не обнуляется.

2 голосов
/ 30 октября 2011

Потому что существует неявное преобразование из DateTime в DateTime? (в отличие от перехода в другую сторону, где вы сделали что-то вроде condition ? EmailMessage.TimeStamp : null.

Но вы все равно должны использовать здесь оператор объединения нуля:

var TS = EmailMessage.TimeStamp ?? DateTime.Now
2 голосов
/ 30 октября 2011

Если EmailMessage.Timestamp равен Nullable<T>, то это единственная допустимая опция. В истинном случае это становится Nullable<DateTime>, который всегда имеет значение; в ложном случае он принимает значение Timestamp, которое может иметь или не иметь значение.

Дальнейший анализ не проводится. Вы можете, однако, использовать EmailMessage.Timestamp.Value, который не обнуляется.

В общем случае свойства могут изменять значение между вызовами, поэтому небезопасно проверять нулевое значение и предполагать, что в следующий раз оно будет нулевым. Здесь этого не произойдет, но именно поэтому компилятор c # не делает никаких предположений.

Простое построение здесь, вероятно:

var ts = EmailMessage.Timestamp ?? DateTime.Now;
1 голос
/ 30 октября 2011

EmailMessage.Timestamp всегда DateTime?.Не имеет значения, проверяете ли вы ранее, является ли оно нулевым или нет.Компилятор не заботится и не должен заботиться.В многопоточном приложении EmailMessage.Timestamp может переключаться между проверкой и тем, где вы используете значение.Форма перспективы компилятора EmailMessage.Timestamp может иметь значение null, если вы используете ее позже, и должна иметь тип DateTime?.

1 голос
/ 30 октября 2011

То, что вы можете после этого, выглядит примерно так:

var TS = EmailMessage.TimeStamp == null ? DateTime.Now : EmailMessage.TimeStamp.Value;

или, возможно,

var TS = (EmailMessage.TimeStamp ?? DateTime.Now).Value;
...