c#:IEnumerable不能在for循环之外工作

时间:2017-02-03 11:07:03

标签: c# asp.net asp.net-mvc linq

在我的Asp.net MVC程序中,我在这样的控制器中有一个动作方法。有两段代码执行相同的功能。问题是,为什么评论代码不起作用?(我查看了视图,评论代码不能生成我想要看到的任何东西,而另一个可以。)我想也许它与for循环有关,因为变量在for-loop结束后,i从内存中消失。任何想法都值得,谢谢。

        //
        // GET: /Account/Register
        [AllowAnonymous]
        public ActionResult Register(string code, string state)
        {
           ……

            var departments = new List<IEnumerable<SelectListItem>>();

            //functionally equal, but not work.
//            for (int i=0; i< db.Settings.Find(1).MaxDepartmentLevel;i++)
//            {
//                departments.Add(ToSelectListItems(db.Departments.Where(r => r.Level == i+1)));
//
//            }

            //these work.
            departments.Add(ToSelectListItems(db.Departments.Where(r => r.Level ==  1)));
            departments.Add(ToSelectListItems(db.Departments.Where(r => r.Level ==2)));
            departments.Add(ToSelectListItems(db.Departments.Where(r => r.Level == 3)));


            var registerViewModel = new RegisterViewModel()
            {
                OpenId = wechatUserAccessToken.openid,
                Departments = departments,
                    AvatarImageUrl = avatarImageUrl.TrimEnd('0') + "96"
            };

            return View(registerViewModel);
        }

编辑: db.Settings.Find(1).MaxDepartmentLevel = 3。

1 个答案:

答案 0 :(得分:2)

这是一个for循环变量闭包问题,由@Ivan的问题评论指出。

事实上,下面的代码不会按照我的意愿执行。

  //functionally equal, but not work.
//            for (int i=0; i< db.Settings.Find(1).MaxDepartmentLevel;i++)
//            {
//                departments.Add(ToSelectListItems(db.Departments.Where(r => r.Level == i+1)));
//
//            }

它将按此执行:

            departments.Add(ToSelectListItems(db.Departments.Where(r => r.Level ==  4)));
            departments.Add(ToSelectListItems(db.Departments.Where(r => r.Level ==4)));
            departments.Add(ToSelectListItems(db.Departments.Where(r => r.Level == 4)));

上方,r.Level == 4因为for循环中的i最后为3,最后为i+1=4

r => r.Level == i+1正在实例化一个委托,该委托捕获变量i 本身但不变量i&#39; 。这与JAVA完全不同。

一些有价值的参考资料:

http://csharpindepth.com/Articles/Chapter5/Closures.aspx

https://blogs.msdn.microsoft.com/ericlippert/2009/11/12/closing-over-the-loop-variable-considered-harmful/

https://stackoverflow.com/a/227833/5835947