public virtual void OnRegistrationJoin(RegistrationJoinEventArgs e)
{
foreach (Mobile member in e.Team)
{
member.SendMessage(1161, "You join the {0}.", EventFullName);
if (e.Team.Count > 1)
{
Joinees.Remove(member);
member.SendMessage(1161, "Your team formation is:");
int i = 0;
foreach (Mobile parter in e.Team.Where(partner => partner != member).ToList())
{
member.SendMessage(1150, "{0}: {1}.", ++i, partner.Name);
}
}
}
Members.Add(e.Team);
}
Run Code Online (Sandbox Code Playgroud)
我通过resharper获得"访问修改后的闭包"警告,我想知道这段代码有什么问题,因为我在内循环中所做的只是发送消息?
cod*_*zen 13
问题在于:
e.Team.Where(partner => partner != member)
Run Code Online (Sandbox Code Playgroud)
变量member是member外部范围中变量的直接引用.虽然您在上面的代码中可能没有遇到此问题,但是当您在多个线程上运行代码或者您没有立即在Where方法中评估lambda时(例如,使用IQueryable而不是IEnumerable),它会出现问题.
这是一个问题的原因是C#生成一个方法然后作为委托传递给Where.该方法需要直接访问memeber.如果您要将引用分配给另一个变量,如下所示:
var m = member;
// ...
e.Team.Where(partner => partner != m);
Run Code Online (Sandbox Code Playgroud)
然后C#可以在称为"闭包"的构造中"捕获"该值,并将其传递给生成的方法.这将确保在member更改时,您传递给它时所期望的值Where不会更改.