0

我在下面的表达式中忽略了什么?Int64 类型的范围不是比 Int16 大吗?

Int64 value = (Int64)(System.Data.SqlTypes.SqlInt16.MaxValue+1);

System.Data.SqlTypes.SqlInt16.MaxValue 是 32767。Int64.MaxValue() 是 9223372036854775807。

32767 + 1 = 32768。这比 9223372036854775807 低很多(!)。

那么为什么我在施放时会得到 Aritmethic 溢出

(Int64)(System.Data.SqlTypes.SqlInt16.MaxValue+1);

到 Int64?

(这与 C# 中 + 运算符的实现有关还是...?)

4

5 回答 5

3

SqlTypes.SqlInt16 是一个有趣的类型。好像很短但事实并非如此,它实际上是一个struct。它有一堆运算符重载,使其表现得像一个数字。请注意此版本如何正常工作:

    Int64 value = (Int64)(short.MaxValue + 1);    // okay

它使用“普通”加法运算符,它永远不会溢出,因为 CLR 实际上没有一个可以简称为加法运算符的加法运算符。它支持的最接近的类型是 Int32,这里不会溢出。

但是 SqlInt16 是为了捕捉这个错误而编写的,它有一个operator+()重载,它被显式地编写来生成这个异常。换句话说,它确实实现了 16 位加法的语义,并在结果不适合 16 位整数类型的 dbase 表列时大喊大叫。无论您在 C# 中使用checked关键字还是unchecked关键字。这是一件好事,当您使用 dbase 时,您真的很想知道这一点。

您需要调用 SqlInt16 的另一个方法,即转换运算符。将 SqlInt16 转换为本机整数类型的一种。诙谐的品种看起来像这样:

   Int64 value = (Int64)((short)System.Data.SqlTypes.SqlInt16.MaxValue + 1);

但是当然直接转换为 Int64 更有意义,SqlInt16 也有一个转换运算符:

   Int64 value = (Int64)System.Data.SqlTypes.SqlInt16.MaxValue + 1;

请注意此类代码的不确定语义。您不能转换 dbase 列。我的第一个片段更有意义。

于 2014-02-20T10:14:05.553 回答
2

您正在尝试将结果SqlInt16.MaxValue+1转换为Int64. 但是SqlInt16.MaxValue是一个SqlInt16。在你施放它之前添加 +1 就会溢出。


您要做的是首先将其SqlInt16.MaxValue转换为Int64然后添加1到它:

Int64 value = (Int64)System.Data.SqlTypes.SqlInt16.MaxValue + 1;
于 2014-02-20T09:50:43.420 回答
1

而是这样做,您尝试将 1 添加到最大值System.Data.SqlTypes.SqlInt16

Int64 value = (Int64)(System.Data.SqlTypes.SqlInt16.MaxValue) +1;
于 2014-02-20T09:50:27.263 回答
1

因为(System.Data.SqlTypes.SqlInt16.MaxValue+1)是一个int16- 或至少试图成为,这是无效的。

只需先投射MaxValueto int64,然后再添加 1。

只是为了举例说明:

var x = (System.Data.SqlTypes.SqlInt16.MaxValue + 0);
var t = x.GetType(); // t will be System.Data.SqlTypes.SqlInt16
于 2014-02-20T09:52:00.880 回答
0

将鼠标悬停+在代码中的符号上,您将弹出一个工具提示,告诉您它(重载解决方案)转到“用户定义”运算符。在该字符上选择“转到定义”或 F12 +,您将看到签名:

public static SqlInt16 operator +(SqlInt16 x, SqlInt16 y);

文档

所以您现在知道右手操作数1被隐式转换为SqlInt16(首先通过 C# 的常量(文字)表达式转换规则隐式转换 from to,然后int通过"user-defined"转换 from to )。然后我们有两个值。上面将它们纳入并希望返回第三个值,即它们的总和。但这是不可能的。出现异常。shortshortSqlInt16implicit operatorSqlInt16operatorSqlInt16

所以我们永远不会得到你的演员表Int64;问题发生在此之前。

要修复它,请在添加 ( )之前System.Data.SqlTypes.SqlInt16.MaxValue显式转换为例如Int64(aka long) 或Int16(aka )。short+

当然,你也可以使用:

long value = short.MaxValue + 1;

因为short.MaxValue与 具有相同的数值SqlInt16.MaxValue,但我不知道您是否可以在您的应用程序中使用它。

于 2014-02-20T13:26:22.417 回答