C#访问修改后的闭包

bev*_*qua 7 c# resharper

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)

变量membermember外部范围中变量的直接引用.虽然您在上面的代码中可能没有遇到此问题,但是当您在多个线程上运行代码或者您没有立即在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不会更改.