C# For 循环使用 var 时的类型推断
考虑下面的代码...
double total = Int32.MaxValue;
total++;
int previousX = 0;
for (var x = 0; x <= total; x++)
{
if (x == Int32.MaxValue)
{
Console.WriteLine("Int32 max reached.");
}
if (x < 0)
{
Console.WriteLine("Counter now < 0.");
}
previousX = x;
}
看起来,如果您将 var 与 for 循环一起使用,则默认类型推断是 int。
这是正确的吗?因为如果计数器超过 int 32 的最大值,它不会溢出堆栈,而是将自身重置为零,然后从零开始倒数。
注意:previousX 允许您设置断点并查看计数器“x”的先前值是什么。
有谁知道为什么会发生这种情况?
使用 var 作为 for 循环的计数器似乎可能会遇到一些麻烦。
Consider the following code...
double total = Int32.MaxValue;
total++;
int previousX = 0;
for (var x = 0; x <= total; x++)
{
if (x == Int32.MaxValue)
{
Console.WriteLine("Int32 max reached.");
}
if (x < 0)
{
Console.WriteLine("Counter now < 0.");
}
previousX = x;
}
It would appear that, if you use var with a for loop the default type inference is of an int.
Is this correct because if the counter goes past the maximum for an int 32, instead of overflowing the stack it resets itself back to zero and then counts down from zero.
Note: previousX allows you to set breakpoints and see what the previous value of the counter "x" was.
Does anyone know why this happens?
It seems possible to get into a bit of a pickle by using var for the counter of a for loop.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
x
的类型由初始值决定,上面是整数文字0
。如果您希望
x
为双精度型,请使用双精度文字0D
。The type of
x
is determined by the initial value, which above is the integer literal0
.If you want
x
to be a double then use the double literal0D
.重要的是要理解 var 关键字并不意味着“变体”,也不表示该变量是松散类型的或后期绑定的。它只是意味着编译器确定并分配最合适的类型。当您有
var x=0
时,它确定x
是int
以便匹配0
。所以是的,这是正确的功能。
由于负数在超过其最大值时的表示方式(二进制补数),它看起来会重置并从 -1 开始倒计时。
在循环迭代完成之前,
x++
上的增量不会发生。It is important to understand that the var keyword does not mean "variant" and does not indicate that the variable is loosely typed, or late-bound. It just means that the compiler determines and assigns the most appropriate type. As you have
var x=0
it determines thatx
is anint
in order to match0
.So yes it is correct functionality.
Because of the manner in which negative numbers are represented (twos compliment) as a number wraps over its maximum value it will appear to reset and count down from -1 onwards.
The increment on
x++
doesn't occur until that iteration of the loop has completed.当然,如果将 int 递增到超过 MaxValue,它将返回到 MinValue 并从那里开始递增。
Of course, if you increment an int past MaxValue, it goes back down to MinValue and starts to increment from there.
这确实很有趣,但与 var 的使用无关。
当使用 int (或者实际上是 long、short 等)时,这种情况仍然会发生。
这里的真正罪魁祸首是循环的最大值大于 int32 的最大值。当数值增加时,数字将换行,导致无限循环。您可以声明 var x、int x、short x,所有这些都将以类似的方式循环。
递增数值的本质会导致“环绕”。您可以通过运行以下代码并观察增量之前和之后的值来尝试。 (如果您添加减量,这也适用)。
顺便说一句,发布的代码片段中的 var 通过语句 var x = 0 设置为 int。“0”本身就是 int,因此 x 的类型设置为 int。如果您声明 var x = 0F 或 0L,则类型会有所不同。
This is indeed interesting but is unrelated to the use of var.
This still happens when using int (or in fact long, short etc).
The actual culprit here is that the MAX value for the loop is larger than the max value for int32. when a numeric value is incremented the number will wrap causing an infinite loop. You can declare var x, int x, short x and ALL of these would loop in a similar manner.
The nature of incrementing numeric values cause 'wrap-around'. You can try it by running the following code and observing the values befor and after the increment. (This also works if you add a decrement).
As an aside, the var in the code snippet posted is being set to an int by the statement var x = 0. The '0' is itself an int and hence the type of x is set to int. If you stated var x = 0F or 0L the type would be different.
Var
确切类型由您使用=
运算符定义。在c#
中,0
是int
类型,因此编译器使用int
。Var
exact type is defined by your usage of=
operator. Inc#
0
is of typeint
so compiler is usingint
.这里没有什么特别的事情发生。
var
将被推断为Int32
,因为这是 0 的默认值。如果你想要长时间使用var x = 0L
。或者只是long x = 0
There's nothing special going on here.
var
will be inferred asInt32
because that's what 0 defaults to. If you want a long usevar x = 0L
. Or justlong x = 0
var x = 0
将推断 x 是一个整数,因为您使用的是整数文字(“0”)。查看有关整数溢出的相关文章:
为什么会这样导致长整型溢出
The
var x = 0
is going to infer that x is an integer because you are using an integer literal ("0").Check out this related post concerning integer overflow:
why this would result in long integer overflow
这看起来很简单:
当编译器看到这一行时,他将
var
替换为User
,因为这就是构造函数返回的内容。函数调用也会发生同样的情况:ToString()
返回string
,因此编译器知道用什么替换var
。当您编写时,
您实际上调用了
int
构造函数,因此var
被替换为int
您有三个选择:
double x = 0 。 ..
var x = 0.0 ...
var x = 0D ...
注意:
D
后缀代表double
This looks quite simple:
When compiler sees this line, he replaces
var
withUser
, because that's what constructor returns. The same happens with function calls:ToString()
returnsstring
, so compiler knows what to replacevar
with.When you write
you actually call
int
constructor, sovar
is replaced with withint
You have three options:
double x = 0 ...
var x = 0.0 ...
var x = 0D ...
Note:
D
suffix is fordouble