1

一連のレコードに対してさまざまなフィルター項目を表すツリービューがあります。実行時に、各ノードのタグを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");

等..

次に、ユーザーがノードをクリックすると、タグを渡して、データを取得するための述語として使用します。

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);
}

問題は、動的に作成されたノードすべてに同じ述語オブジェクトが含まれていることです(これは、最後の前の反復中に作成された同じ述語のようです)。

ここで何が起こっているのかよくわかりません。何か案が?どうもありがとう!

4

3 に答える 3

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);
}
于 2010-10-27T19:23:50.397 に答える
0
(Func<MyRecordType, bool>)(p=> p.CreatedBy == user);

動作するはずです。

于 2010-10-27T19:23:15.103 に答える
0

Func <>オブジェクトを作成すると、ユーザー変数の現在の値は保存されず、ループの反復で共有される変数を操作します。ただし、ループ内に変数の新しいコピーを作成すると、機能します。

例:代わりに:

        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);
        }
于 2010-10-27T19:32:17.053 に答える