c# – 重现“接近foreach的变量”

前端之家收集整理的这篇文章主要介绍了c# – 重现“接近foreach的变量”前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
使用Visual Studio 2013,我试图重现Eric Lippert的博客文章 “Closing over the loop variable considered harmful”提到的getcha.

在项目属性中,我选择“C#3.0”作为语言版本(Build> Advanced …).此外,我选择了“.NET Framework 3.5”作为目标框架,好像我认为这不应该是必要的,因为这只是关于语言.

运行他的代码

using System;
using System.Collections.Generic;

namespace Project1
{
    class Class1
    {
        public static void Main(string[] args)
        {
            var values = new List<int>() { 100,110,120 };
            var funcs = new List<Func<int>>();
            foreach (var v in values)
            {
                funcs.Add(() => v);
            }
            foreach (var f in funcs)
                Console.WriteLine(f());
        }
    }
}

预期产量:

120
120
120

实际输出

100
110
120

正如“Is there a reason for C#’s reuse of the variable in a foreach?” 0700所示:

The for loop will not be changed,and the change will not be “back ported” to prevIoUs versions of C#. You should therefore continue to be careful when using this idiom.

我究竟做错了什么?

解决方法

斯科特的答案是正确的,但可以使用一些额外的澄清.

这里的问题是“语言版本”开关不能做你认为的.在我看来,这是一个非常错误的,因为它是非常误导的. “语言版本”开关并不意味着“使用旧的编译器”;它不是兼容模式.

相反,它意味着“使用当前的编译器,并且如果我使用在所选语言版本中不可用的功能,则会产生错误”.

这个切换的原因是,开发团队中的一个人可以“尝试”一个新版本的编译器,以确保他们的代码仍然有效,但是在他们检查之前知道他们没有意外地使用一个语言功能他们的队友的编辑者会窒息.所以如果你将语言版本设置为3.0,那么“动态”将不起作用(因为它被添加到C#4.0中),但它仍然是您安装的任何版本的编译器.

正如Scott指出的,如果你想使用旧的编译器,你必须在你的机器上实际找到一个旧的编译器的副本并明确使用它.

有关这个交换机所做的和不做的更多例子,请参见http://ericlippert.com/2013/04/04/what-does-the-langversion-switch-do/.

原文链接:https://www.f2er.com/csharp/95658.html

猜你在找的C#相关文章