Reputation: 10229
In my Asp.net MVC program, I have an action method in a controller like this. There are two pieces of codes which perform the same functionality. The question is, why the comment codes not work?(I checked the view, the comment codes cannot generate anything I desire to see, while the other can.) I guess maybe it has something to do with the for-loop, because variable i
disappear from memory after the for-loop end. Any thought is of worth, thanks.
//
// 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);
}
Edit:
db.Settings.Find(1).MaxDepartmentLevel
=3.
Upvotes: 0
Views: 126
Reputation: 10229
It's a for loop variable closure issue, which is pointed out by @Ivan in question's comment.
In fact, the code below will not perform as I wish.
//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)));
//
// }
It will perform as this:
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)));
Above, r.Level == 4
because i
in for-loop will be 3
finally and i+1=4
at last.
r => r.Level == i+1
is instantiating a delegate, which capture variable i
itself but not variable i
's value. This is totally different from JAVA.
Some valuable references:
http://csharpindepth.com/Articles/Chapter5/Closures.aspx
https://stackoverflow.com/a/227833/5835947
Upvotes: 2