2016-10-18 2 views
0

Когда я сравниваю переменную DateTime с SqlDateTime.MinValue:Сравнивая DateTime с SqlDateTime.MinValue

if (StartDate > SqlDateTime.MinValue) 
{ 
    // some code 
} 

Я получаю следующее исключение во время выполнения, если StartDate является < SqlDateTime.MinValue:

переполнения SqlDateTime. Должно быть между 1/1/1753 12:00:00 и 31.12.19999 11:59:59 PM.

Это может быть легко решена с небольшим изменением:

if (StartDate > SqlDateTime.MinValue.Value) 
{ 
    // some code 
} 

Я понимаю, что в первом фрагменте кода я сравнивать яблоки с апельсинами. То, что я не понимаю, является сообщением об исключении. Кажется, я присваиваю значение DateTime переменной SqlDateTime.

Что мне не хватает?

+0

Первое, если не выбрасывает исключение. https://dotnetfiddle.net/dBziSf – mybirthname

+0

Я забыл указать, что это произошло, когда StartDate был ниже SqlDateTime.MinValue – Gnomo

+1

Компилятор ищет способ сравнить два совершенно разных класса. Единственный способ, которым это может сделать, - использовать [перегрузку оператора] (https://referencesource.microsoft.com/#System.Data/System/Data/SQLTypes/SQLDateTime.cs,514), который предоставляет SqlDateTime. Но для этого требуется преобразовать DateTime в SqlDateTime. И это бросает. Выбранная вами альтернатива использует перегрузку оператора, предоставляемую DateTime. –

ответ

1

Свойственный тип DateTime .NET (в частности, его структура) содержит более широкий диапазон возможных значений, чем может поддерживать тип данных SqlDateTime. Более конкретно, значение DateTime может варьироваться от 01/01/0000 до теоретического 12/31/9999.

Когда компилятор пытается принудить типы для сравнения, он пытается поместить значение DateTime (MinValue.Value), находящееся снаружи (ниже или «до» в контексте) диапазон, поддерживаемый SqlDateTime - следовательно, переполнение.

+0

Зачем ему пытаться принудить первого операнда ко второму, а не наоборот? – Gnomo

+0

Я считаю, что компилятор интерпретирует оператор сравнения как оператор, определяемый SqlDataType, и, таким образом, пытается преобразовать сравниваемый элемент в SqlDateTime через неявное преобразование. –

+1

Я думал, что вопрос @ Гномо заслуживает лучшего ответа, чем я предлагал. В частности, переполнение происходит из-за того, что механизм разрешения * разрешающей способности C# выбрал перегрузку для «меньше» оператора '<', связанного с тем, что в «ближайшем» классе - «SqlDateTime», и параметры для этой перегрузки, естественно , два объекта SqlDateTime.Затем C# замечает неявное преобразование из DateTime в SqlDateTime и пытается назначить предоставленное значение, которое затем переполняется. См. Замечательный комментарий Эрика Липперта о «близости» на https://ericlippert.com/2013/12/23/closer-is-better/ –

0

От SqlDateTime Structure на MSDN:

структура SqlDateTime

Представляет данные о дате и времени в диапазоне стоимости от 1 января 1753 г. по 31 декабря 9999 с точностью до 3,33 мс, чтобы быть хранится или извлекается из базы данных. Структура SqlDateTime имеет другую базовую структуру данных из соответствующего типа .NET Framework DateTime, который может представлять любое время между 12:00:00 AM 1/1/0001 и 11:59:59 PM 12/31/9999, до точность 100 наносекунд. SqlDateTime фактически сохраняет относительную разницу до 00:00:00 AM 1/1/1900. Поэтому преобразование из числа «00:00:00 AM 1/1/1900» в целое число будет возвращаться 0.

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