2016-08-26 5 views
1

再帰的にオブジェクトが「構築中」のときに、オブジェクト(または参照)を関数に渡す方法はありますか?私は彼の子供の中に親ノードを保持したい。親ノードを再帰的に渡す

いくつかの方法で行わを呼び出す:

NavigationTreeNode node = FindNode(Resources.ShellView_TreeNodeBusinessRules); 
var tmpList = LoadNodes(xDoc.Descendants("root").Elements("tab"), node); 

そして、これが再帰です:あなたはラムダ式の範囲を指定するには、{}を追加することができ、その後、あなたの新しいオブジェクトを保存することができます

private List<NavigationTreeNode> LoadNodes(IEnumerable<XElement> nodes, NavigationTreeNode parentNode) 
{ 
    return nodes.Select(x => 
     new NavigationTreeNode(x.Attribute("display-name").Value, parentNode) 
     { 
      TabName = x.Attribute("tab-name").Value, 
      // Here I want to send object that is now under 
      // construction, or maybe reference 
      ChildNodes = LoadNodes(x.Elements("tab"), /* ?? */) 
     }).ToList(); 
} 

答えて

2

変数にプロパティを設定して返します。

return nodes.Select(x => 
{ 
    var obj = new NavigationTreeNode(x.Attribute("display-name").Value, parentNode) 
    { 
     TabName = x.Attribute("tab-name").Value 
    }; 
    obj.ChildNodes = LoadNodes(x.Elements("tab"), obj); 
    return obj; 
}).ToList(); 
+0

驚くべき男、それは動作します!私はLINQでより多くの運動が必要です。 FYI、はい、それは単なる文字列です。 –

+0

@p__d - この編集が今でもあなたに合っているかどうか教えてください –

+0

ここでは何が再帰を破りますか? –

0

あなたがナビゲーションクラスを再設計したならば、これは正直なところより良い結果が得られます。この特定のケースでは、構造体は再帰的に再構築するためにlinqを使用することには適していません。 linq を使用して再帰構造を初期化することができますが、構造が二重にリンクされている場合は効果的に利用できません。

一般に、構造を初期化するときに使用する子のリストを作成するのは間違いです。内部構造に直接アクセスできるようになると、カプセル化が中断されます。とにかくそれらを操作するメソッドを提供する必要があります。このような構造を持つ例えば

、それは物事が非常に簡単になるだろう:

class NavigationTreeNode 
{ 
    private List<NavigationTreeNode> childNodes = new List<NavigationTreeNode>(); 
    public NavigationTreeNode(string tabName, string displayName) 
    { 
     TabName = tabName; 
     DisplayName = displayName; 
    } 
    public NavigationTreeNode Parent { get; private set; } 
    public string TabName { get; } 
    public string DisplayName { get; } 
    public IReadOnlyList<NavigationTreeNode> ChildNodes => childNodes.AsReadOnly(); 

    public void Add(NavigationTreeNode childNode) 
    { 
     if (childNode.Parent != null) 
      childNode.Parent.Remove(childNode); 
     childNodes.Add(childNode); 
     childNode.Parent = this; 
    } 

    private void Remove(NavigationTreeNode childNode) 
    { 
     childNodes.Remove(childNode); 
     childNode.Parent = null; 
    } 
} 

次にロード機能は、次のようになります。あなたが望むどのくらいの

private NavigationTreeNode LoadNode(XElement node) 
{ 
    var treeNode = new NavigationTreeNode((string)node.Attribute("tab-name"), (string)node.Attribute("display-name")); 
    foreach (var tab in node.Elements("tab")) 
     treeNode.Add(LoadNode(tab)); 
    return treeNode; 
} 

と依存をデザインと一緒に行くには、ループの必要性を完全に取り除き、linqを使って完全に書くことができます。私はあなたのためにそれを運動として残します。

関連する問題