遇到与Func的障碍

时间:2010-10-27 19:19:59

标签: c# func

我有一个树视图,它表示一组记录的不同过滤项。在运行时,我将每个节点的标记设置为Func类型。例如:

myTreeView.Nodes.Add(New TreeNode("Node1"));
myTreeView.Nodes["Node1"].Tag = New Func<MyRecordType, bool>(p=> p.Title == "test 1");

myTreeView.Nodes.Add(New TreeNode("Node2"));
myTreeView.Nodes["Node2"].Tag = New Func<MyRecordType, bool>(p=> p.Title == "test 2");

等。

然后,当用户点击该节点时,我只是传递Tag并将其用作获取数据的谓词:

gridView.DataSource = populateData(nodeClicked.Tag as Func<MyRecordType, bool>);

private MyRecordType[] populateData(Func<MyRecordType, bool> predicate)
{
  MyRecordType[] records;

  if(predicate == null)
     records = MyRecords.ToArray();
  else
    records = MyRecords.Where(predicate).ToArray();

  return records;
}

这一切都很有效,但我添加了一些基于一组记录创建节点的代码。它看起来像这样:

var users = DB.MyRecords.OrderBy(o=> o.CreatedBy).Select(s=> s.CreatedBy).Distinct();

foreach(var user in users) {
  var node = new TreeNode("Node" + user, user);
  node.Tag = new Func<MyRecordType, bool>(p=> p.CreatedBy == user);
  MyTreeView.Nodes.Add(node);
}

问题在于动态创建的节点都包含相同的谓词对象(它似乎与上一次forearch迭代期间创建的谓词相同)。

我不确定这里发生了什么。任何的想法?万分感谢!

3 个答案:

答案 0 :(得分:2)

您正在捕获非本地变量,即user

在循环内创建一个临时文件并改为引用它。

示例:

foreach(var user in users) {
  var u = user;
  var node = new TreeNode("Node" + user, user);
  node.Tag = new Func<MyRecordType, bool>(p=> p.CreatedBy == u);
  MyTreeView.Nodes.Add(node);
}

答案 1 :(得分:0)

(Func<MyRecordType, bool>)(p=> p.CreatedBy == user);

应该有用。

答案 2 :(得分:0)

创建Func&lt;&gt;时对象,存储用户变量的当前值,而是对循环迭代共享的变量进行操作。如果你在循环中创建变量的新副本,它将会工作。

,例如,而不是:

        foreach (string s in new string[] { "1", "2", "3" })
            funcs.Add(() => s);

使用

        foreach (string s in new string[] { "1", "2", "3" })
        {
            string s1 = s;
            funcs.Add(() => s1);
        }