为什么c#不允许将SqlDatetime.MinValue分配给datetime但允许比较

时间:2015-06-03 02:56:15

标签: c# datetime sqldatetime

以下代码与comparison运算符编译良好。

If(dateTimeVariable > SqlDateTime.MinValue) //compiles Ok. dateTimeVariable is of type DateTime
{
}

但是,以下代码无法编译。

DateTime dateTimeVariable=SqlDateTime.MinValue;
//Throws exception , cannot convert source type SqlDateTime to DateTime. Which is obvious.

我的问题是为什么在comparisonSqlDateTime类型之间允许Datetime但不允许assignment。 (除非comparison运营商正在进行一些implicit转换。)

我猜我必须遗漏一些非常基本的东西。

2 个答案:

答案 0 :(得分:2)

SqlDateTime中进行隐式转换,负责将DateTime转换为SqlDateTime而无需任何额外工作:

public static implicit operator SqlDateTime(DateTime value)
{
    return new SqlDateTime(value);
}

// SqlDateTime mySqlDate = DateTime.Now

必须发生的事情是dateTimeVariable被隐式转换为DateTimeSqlDateTime进行比较:

if (dateTimeVariable > SqlDateTime.MinValue)
{
    // if dateTimeVariable, after conversion to an SqlDateTime, is greater than the
    //  SqlDateTime.MinValue, this code executes
}

但是在以下代码的情况下,没有什么可以让您简单地将SqlDateTime填充到DateTime变量中,因此它不允许它。< / p>

DateTime dateTimeVariable = SqlDateTime.MinValue;  // fails

投出您的初始值,它会编译好,但是您有可能会丢失属于SqlDateTime但不是DateTime的有价值信息。

DateTime dateTimeVariable = (DateTime)SqlDateTime.MinValue;

答案 1 :(得分:2)

这是一个潜在的精度损失问题。通常这发生在“缩小”与“扩大”的背景下。

整数是数字的子集。所有整数都是数字,有些数字不是整数。因此,类型“数字”比“整数”类型宽。

您始终可以将类型分配给更宽的类型而不会丢失信息。

缩小是另一回事。要将1.3分配给整数,您必须丢失信息。这是可能的,但编译器不会执行缩小转换,除非您明确声明这是您想要的。

因此,自动和隐式转换需要扩展转化的分配,但缩小分配需要显式转换或转换(并非所有转换都是简单转换)。

虽然可以说SqlDateTimeDateTime更窄但代表性差异意味着两个方向的转化都可能有损。因此,要将SqlDateTime分配给DateTime,需要进行显式转换。严格地说,将DateTime转换为SqlDateTime应该要求显式转换,但是在SqlDateTime类型中实现的隐式转换(qv Grant的答案)使得SqlDateTime 表现就好像它更宽。我犯了错误,假设SqlDateTime更宽,因为这就是它在这种情况下的表现,并且很多赞赏评论者选择这个重要的微妙之处。

这种隐式转换实际上是VARCHAR列和ADO.NET隐式类型参数的一个问题,因为C#字符串是Unicode并且变为NVARCHAR,因此将它们与VARCHAR类型的索引列进行比较将导致扩展转换为NVARCHAR(隐式扩展转换事件也发生在TSQL中),它可以阻止使用索引 - 这不会阻止查询返回正确的结果但会削弱性能。

来自MSDN

SqlDateTime结构

表示从1753年1月1日到9999年12月31日的值的日期和时间数据,以及存储在数据库中或从数据库中检索的3.33毫秒的准确度。 SqlDateTime结构与其对应的.NET Framework类型DateTime具有不同的基础数据结构,可以表示在12:00到AM 1/1/0001和12/31/59 PM 12/31/9999之间的任何时间到精度为100纳秒。 SqlDateTime实际上存储了相对差异到00:00:00 AM 1/1/1900。因此,从“00:00:00 AM 1/1/1900”到整数的转换将返回0.