Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/EmptyTag/133.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 是否每次迭代都对for循环中的条件进行评估?_C#_.net_Loops - Fatal编程技术网

C# 是否每次迭代都对for循环中的条件进行评估?

C# 是否每次迭代都对for循环中的条件进行评估?,c#,.net,loops,C#,.net,Loops,当你做以下事情时: for (int i = 0; i < collection.Count; ++i ) for(int i=0;i

当你做以下事情时:

for (int i = 0; i < collection.Count; ++i )
for(int i=0;i
是否在每次迭代时都调用collection.Count


如果Count属性动态获取调用计数,结果是否会更改?

每次传递时都会计算计数。如果您继续添加到集合中,而迭代器从未跟上,那么您将有一个无休止的循环

class Program
    {
        static void Main(string[] args)
        {
            List<int> intCollection = new List<int>();
            for(int i=-1;i < intCollection.Count;i++)
            {
                intCollection.Add(i + 1);
            }
        }
    }
类程序
{
静态void Main(字符串[]参数)
{
List intCollection=新列表();
for(inti=-1;i

这最终会导致内存不足异常。

从i初始化后的第一次迭代到检查失败并退出for循环的最后一次迭代,每次调用时都会检查Yes count。如果需要,您可以修改集合计数,但要意识到最终可能会陷入一个无休止的循环。

每次通过时都会计算“是”计数。原因是在循环执行期间可以修改集合。给定循环结构,变量i应该在迭代期间表示集合中的有效索引。如果没有对每个循环进行检查,那么这是不可证明的。例

class Program
    {
        static void Main(string[] args)
        {
            List<int> intCollection = new List<int>();
            for(int i=-1;i < intCollection.Count;i++)
            {
                intCollection.Add(i + 1);
            }
        }
    }
for ( int i = 0; i < collection.Count; i++ ) {
  collection.Clear();
}
for(int i=0;i
此规则的一个例外是在约束为长度的数组上循环

for ( int i = 0; i < someArray.Length; i++ ) {
  // Code
}
for(int i=0;i
在某些情况下,由于数组的长度不能更改,CLR JIT将对这种类型的循环进行特殊处理。在这些情况下,边界检查只会发生一次


参考资料:

侧注,VB中的每个交互都不会检查此项

与C#不同,VB缓存collection.Count的结果

编辑:

C#for循环的文字VB版本为:

Dim i = 0
Do While i < collection.Count
    'code goes here
    i+=1
Loop
Dim i=0
趁我不在的时候做。数一数
“代码在这里
i+=1
环

就像这里的其他答案一样:是的,原则上

有(至少)一个明显的异常,array.Length。在

for (int i = 0; i < a.Length; i++) a[i] = ...;
for(inti=0;i

“长度”属性将只计算一次。这是一个硬连接到编译器中的优化。将来可能会有其他类似的情况,但前提是保证不会对可观察的行为产生影响。

C#是否会阻止您在迭代过程中修改集合?或者这只在for-each循环中发生?只在使用Enumerators@jeffamaphone-我也这么想,但我写了一个小程序,证明它不是。有趣。OP没有说明集合是什么,但我在测试中使用了一个列表。但据我所知,这个编译器是JIT编译器,而不是C编译器。@John:不确定,两个编译器都知道数组是固定的。通过查看IL,我猜是C#编译器。如果我调整循环中数组的大小会怎么样?@Joan。。。你为什么不试试呢?像我上面展示的那样,构建一个小测试应用程序需要60秒的时间。新项目,控制台应用程序…我可以试试,但我在我朋友的电脑上。可以使用snipper编译器,但不想安装任何东西。所以,如果在迭代时更改集合,它会被破坏吗?如果你想在循环时更改集合,你需要使用循环。如果我在循环中调整数组大小怎么办?@Henk,是的,这是启发式的一部分,它决定了他们是否可以在这个循环中使用特殊情况。@Jared:但是数组有一个静态调整大小的方法,对吗?这就是我的意思,虽然可能会分配一个新数组。另外,当你说“这是启发式的一部分”时,你的意思是编译器也认识到了这一点吗?@Jaredpar,我开始有了第二个想法——我们不是把它与边界检查优化混淆了吗?Length属性被转换成一个ldlen操作码,我称之为内联。@Joan,是的,有一个Resize,但它创建了一个新数组。注:第一个参数通过引用获取。