2

以下代码使用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.

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

我猜我一定错过了一些非常基本的东西。

4

2 回答 2

2

有一个隐式转换SqlDateTime负责将 a 转换为 aDateTimeSqlDateTime无需任何额外工作:

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

// SqlDateTime mySqlDate = DateTime.Now

必须发生的事情是dateTimeVariable从 a 隐式转换为 aDateTimeSqlDateTime进行比较:

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

但是在以下代码的情况下,没有什么可以让您简单地将 an 填充SqlDateTimeDateTime变量中,因此它不允许这样做。

DateTime dateTimeVariable = SqlDateTime.MinValue;  // fails

转换你的初始值,它会编译好的,但是你有可能会丢失一些有价值的信息,这些信息是 a 的一部分,SqlDateTime但不是 a 的一部分DateTime

DateTime dateTimeVariable = (DateTime)SqlDateTime.MinValue;
于 2015-06-03T03:01:10.640 回答
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: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。

于 2015-06-03T03:20:52.393 回答