c#编译器是否优化了Count属性?

Vit*_*liy 12 c# compiler-construction optimization

List<int> list = ...

for(int i = 0; i < list.Count; ++i)
{
           ...
}
Run Code Online (Sandbox Code Playgroud)

那么编译器是否知道list.Count不必每次迭代都被调用?

Dan*_*Tao 22

你确定吗?

List<int> list = new List<int> { 0 };

for (int i = 0; i < list.Count; ++i)
{
    if (i < 100)
    {
        list.Add(i + 1);
    }
}
Run Code Online (Sandbox Code Playgroud)

如果编译器缓存了Count上面的属性,则内容list将为0和1.如果不是,则内容将是0到100之间的整数.

现在,这对你来说似乎是一个人为的例子; 但是这个怎么样?

List<int> list = new List<int>();

int i = 0;
while (list.Count <= 100)
{
    list.Add(i++);
}
Run Code Online (Sandbox Code Playgroud)

看起来好像这两个代码片段完全不同,但这只是因为我们倾向于考虑for循环与while循环.在任何一种情况下,每次迭代都会检查变量的值.在任何一种情况下,这个价值都可以改变.

通常,当相同代码的"优化"和"非优化"版本之间的行为实际上不同时,假设编译器优化某些东西是不安全的.

  • @Neil:这是OP所犯的错误,认为`for`循环与迭代相同.它可能总是在实践中以这种方式使用*但根据定义,它并不是真正的*.它本质上是一个'while`循环.您可能正在考虑`foreach`,*根据定义*是枚举.这将引发异常,因为如果在调用之间修改了列表,`List <T> .Enumerator.MoveNext`将抛出`InvalidOperationException`.无论如何,上面的`for`循环确实可以编译; 自己尝试一下. (2认同)

Ree*_*sey 9

C#编译器不会像这样进行任何优化.但是,JIT编译器对数组进行了优化,我认为(不可调整大小),但不适用于列表.

List的count属性可以在循环结构中更改,因此这将是一个不正确的优化.