以下代码与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
和SqlDateTime
类型之间允许Datetime
但不允许assignment
。 (除非comparison
运营商正在进行一些implicit
转换。)
我猜我必须遗漏一些非常基本的东西。
答案 0 :(得分:2)
在SqlDateTime
中进行隐式转换,负责将DateTime
转换为SqlDateTime
而无需任何额外工作:
public static implicit operator SqlDateTime(DateTime value)
{
return new SqlDateTime(value);
}
// SqlDateTime mySqlDate = DateTime.Now
必须发生的事情是dateTimeVariable
被隐式转换为DateTime
到SqlDateTime
进行比较:
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分配给整数,您必须丢失信息。这是可能的,但编译器不会执行缩小转换,除非您明确声明这是您想要的。
因此,自动和隐式转换需要扩展转化的分配,但缩小分配需要显式转换或转换(并非所有转换都是简单转换)。
虽然可以说SqlDateTime
比DateTime
更窄但代表性差异意味着两个方向的转化都可能有损。因此,要将SqlDateTime分配给DateTime,需要进行显式转换。严格地说,将DateTime转换为SqlDateTime应该要求显式转换,但是在SqlDateTime类型中实现的隐式转换(qv Grant的答案)使得SqlDateTime 表现就好像它更宽。我犯了错误,假设SqlDateTime更宽,因为这就是它在这种情况下的表现,并且很多赞赏评论者选择这个重要的微妙之处。
这种隐式转换实际上是VARCHAR列和ADO.NET隐式类型参数的一个问题,因为C#字符串是Unicode并且变为NVARCHAR,因此将它们与VARCHAR类型的索引列进行比较将导致扩展转换为NVARCHAR(隐式扩展转换事件也发生在TSQL中),它可以阻止使用索引 - 这不会阻止查询返回正确的结果但会削弱性能。
来自MSDN
表示从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.