C# For 循环使用 var 时的类型推断

发布于 2024-12-14 01:40:50 字数 739 浏览 2 评论 0原文

考虑下面的代码...

            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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

孤独患者 2024-12-21 01:40:50

x 的类型由初始值决定,上面是整数文字0

如果您希望 x 为双精度型,请使用双精度文字 0D

The type of x is determined by the initial value, which above is the integer literal 0.

If you want x to be a double then use the double literal 0D.

拔了角的鹿 2024-12-21 01:40:50

重要的是要理解 var 关键字并不意味着“变体”,也不表示该变量是松散类型的或后期绑定的。它只是意味着编译器确定并分配最合适的类型。当您有 var x=0 时,它确定 xint 以便匹配 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 that x is an int in order to match 0.
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.

捶死心动 2024-12-21 01:40:50

当然,如果将 int 递增到超过 MaxValue,它将返回到 MinValue 并从那里开始递增。

Of course, if you increment an int past MaxValue, it goes back down to MinValue and starts to increment from there.

归属感 2024-12-21 01:40:50

这确实很有趣,但与 var 的使用无关。
当使用 int (或者实际上是 long、short 等)时,这种情况仍然会发生。

这里的真正罪魁祸首是循环的最大值大于 int32 的最大值。当数值增加时,数字将换行,导致无限循环。您可以声明 var x、int x、short x,所有这些都将以类似的方式循环。

递增数值的本质会导致“环绕”。您可以通过运行以下代码并观察增量之前和之后的值来尝试。 (如果您添加减量,这也适用)。

        int a = Int32.MaxValue;
        Console.WriteLine(a);
        a++;
        Console.WriteLine(a);

        short b = Int16.MaxValue;
        Console.WriteLine(b);
        b++;
        Console.WriteLine(b);

        long c = Int64.MaxValue;
        Console.WriteLine(c);
        c++;
        Console.WriteLine(c);

顺便说一句,发布的代码片段中的 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).

        int a = Int32.MaxValue;
        Console.WriteLine(a);
        a++;
        Console.WriteLine(a);

        short b = Int16.MaxValue;
        Console.WriteLine(b);
        b++;
        Console.WriteLine(b);

        long c = Int64.MaxValue;
        Console.WriteLine(c);
        c++;
        Console.WriteLine(c);

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.

剧终人散尽 2024-12-21 01:40:50

Var 确切类型由您使用 = 运算符定义。在c#中,0int类型,因此编译器使用int

Var exact type is defined by your usage of = operator. In c# 0 is of type int so compiler is using int.

花伊自在美 2024-12-21 01:40:50

这里没有什么特别的事情发生。 var 将被推断为 Int32,因为这是 0 的默认值。如果你想要长时间使用var x = 0L。或者只是long x = 0

There's nothing special going on here. var will be inferred as Int32 because that's what 0 defaults to. If you want a long use var x = 0L. Or just long x = 0

回忆凄美了谁 2024-12-21 01:40:50

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

苦行僧 2024-12-21 01:40:50

这看起来很简单:

var x = new User()

当编译器看到这一行时,他将 var 替换为 User,因为这就是构造函数返回的内容。函数调用也会发生同样的情况:

var x = y.ToString()

ToString() 返回 string,因此编译器知道用什么替换 var

当您编写时,

var x = 0

您实际上调用了 int 构造函数,因此 var 被替换为 int

您有三个选择:

  • double x = 0 。 ..
  • var x = 0.0 ...
  • var x = 0D ...

注意:D 后缀代表 double

This looks quite simple:

var x = new User()

When compiler sees this line, he replaces var with User, because that's what constructor returns. The same happens with function calls:

var x = y.ToString()

ToString() returns string, so compiler knows what to replace var with.

When you write

var x = 0

you actually call int constructor, so var is replaced with with int

You have three options:

  • double x = 0 ...
  • var x = 0.0 ...
  • var x = 0D ...

Note: D suffix is for double

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文