This is a question of potential loss of precision. Usually this occurs in the context of "narrowing" versus "widening".
Integers are a subset of numbers. All integers are numbers, some numbers are not integers. Thus, the type "number" is wider than the type "integer".
You can always assign a type to a wider type without losing information.
Narrowing is another matter. To assign 1.3 to an integer you must lose information. This is possible but the compiler won't perform a narrowing conversion unless you explicitly state that this is what you want.
As a result, assignments that require a widening conversion are automatically and implicitly converted, but narrowing assignments require explicit casting or conversion (not all conversions are simple casting).
Although arguably SqlDateTime
is narrower than DateTime
differences in representation mean that conversions in both directions are potentially lossy. As a result, to assign a SqlDateTime to a DateTime requires an explicit conversion. Conversion of DateTime to SqlDateTime strictly speaking ought to require explicit conversion but the implicit conversion implemented in the SqlDateTime type (qv Grant's answer) makes SqlDateTime behave as though it were wider. I made the mistake of assuming SqlDateTime was wider because that's how it's behaving in this case and many kudos to commenters for picking out this important subtlety.
This implicit conversion thing is actually a bit of an issue with VARCHAR columns and ADO.NET implicitly typed parameters, because C# strings are Unicode and become NVARCHAR, so comparing them to an indexed column of type VARCHAR will cause a widening conversion to NVARCHAR (the implicit widening conversions thing also occurs in TSQL), which can prevent the use of the index - which won't stop the query from returning the correct results but will cripple performance.
From MSDN
SqlDateTime Structure
Represents the date and time data ranging in value from January 1, 1753 to December 31, 9999 to an accuracy of 3.33 milliseconds to be stored in or retrieved from a database. The SqlDateTime structure has a different underlying data structure from its corresponding .NET Framework type, DateTime, which can represent any time between 12:00:00 AM 1/1/0001 and 11:59:59 PM 12/31/9999, to the accuracy of 100 nanoseconds. SqlDateTime actually stores the relative difference to 00:00:00 AM 1/1/1900. Therefore, a conversion from "00:00:00 AM 1/1/1900" to an integer will return 0.