Лучше DateTime? или использовать значение по умолчанию (DateTime) для NULL?
Я разрабатываю веб-сайт С#/NHibernate, в котором есть частная система обмена сообщениями. Я бы хотел, чтобы администраторы проверяли, когда и когда сообщение было прочитано пользователем, и вместе выделите те сообщения, которые еще не были прочитаны пользователями. Для достижения обоих я нашел два варианта:
Вариант 1
class Message
{
DateTime? Read;
}
где Read==null
означает, что еще не прочитано
Вариант 2
class Message
{
DateTime Read;
}
где Read==default(DateTime)
(1 января 1 A.D., 0:00:00) означает, что еще не прочитано.
В университете меня научили использовать значение NULL
для обработки всех особых случаев, а также использование типа с нулевым значением кажется хорошим выбором, так как проще читать непрочитанные сообщения, проверяя, являются ли они NULL
или нет.
Но, используя типы с нулевым значением, по крайней мере, включает в себя бокс и распаковку в коде, при этом производительность снижается. С другой стороны, запрос на непрочитанные сообщения означает сравнение значения (но его можно индексировать)
Мой вопрос
Каков ваш предложенный подход для этого? Что предложили бы лучшие практики в этом случае?
Ответы
Ответ 1
Используйте DateTime?
. Его особая цель - избегать использования зарезервированных значений (иначе называемых "магическими числами" ) для представления особых случаев, таких как null
.
Кроме того, использование типа с нулевым значением не вводит сам бокс. Любые значения, которые были бы помещены в коробку, будут, но вы не будете вводить какой-либо бокс просто путем переключения. Тип Nullable<T>
на самом деле является структурой, а возможность сравнения с null
(или Nothing
в VB.NET) является строго условным языком. Под обложками он преобразуется в проверку свойства HasValue
.
Ответ 2
Использование типов с нулевым значением существенно не снижает производительность по сравнению с альтернативными подходами. Оба DateTime
и DateTime?
являются структурами, и здесь нет бокса. Использование нулевого значения - правильный выбор.
Ответ 3
Задайте себе один и тот же вопрос при работе с числовыми значениями. Использую ли я 0? Что делать, если 0 имеет реальный смысл? NULL - это отсутствие ценности. 99 раз из 100, пойти с тем, что делает цель кода наиболее очевидной. Что касается производительности, даже если она есть, она будет бледна по сравнению с любыми проблемами производительности, присущими вашему собственному коду.
Ответ 4
Как сказал Марк и Адам, нулевой тип - это путь. Вы не увидите хита производительности, и это сделает запрос намного проще.
Ответ 5
Чтобы понять, что сказал Марк, если у вас возникла проблема с использованием нулевого типа в клиентском коде, вы можете установить его на DateTime.MinValue
, а затем на уровне buisiness, переключиться на значение NULL. Затем вы можете подавать нулевой тип в DataAccess. Это помогает сохранить слой абстракции для использования нулевых значений.
Ответ 6
Мне не хватает трюка?
class Message
{
DateTime LastRead;
bool Read;
}