1

壁に頭をぶつけても、その日の1つになることもありますが、最も単純な作業でさえもほのめかします(これはその日の1つです!)。

だから私が持っているのはカテゴリーのリストです

CategoryID, CategoryName, ParentID, Lineage
1           Root Category,  NULL,   /1/
2           Child Category, 1,      /1/2/
3           Grandchild,     2,      /1/2/3 
4           Second Root,    NULL,   /4/
5           Second Child    2,      /1/2/5/

上記のすべての値に加えて、これを保持するクラスを作成しました

ICollection<Category> Children;      

これでツリーが作成されます

Root Category 
`-- Child category
|   `-- Grandchild
`-- Second Child
Second Root

そこで、リネージュと要素を指定してツリーに新しいカテゴリを追加しようとしています。リネージュをキューに変換して、この関数にスローします。

public void AddToTree(ref Category parentCategory, Category newCategory, Queue<Guid>lineage)
    {

        Guid lastNode = lineage.Dequeue();

        if(lastNode == newCategory.CategoryId)
        {
            parentCategory.Children.Add(newCategory);
            return;
        }

        foreach (var category in parentCategory.Children)
        {
            if(category.CategoryId == lastNode)
            {
                this.AddToTree(ref category, newCategory, lineage);
            }
        }
    }

今私が得ている2つの問題

  1. 自己参照はそれほど心配する必要はありませんが(再帰的に設計されています)、foreachループ内のカテゴリはローカルでインスタンス化された変数であるため、参照によって作成してポインタとして使用することはできません。

  2. これよりも簡単な方法があるはずです!

どんなポインタも大いに受け取られるでしょう。

4

2 に答える 2

1

このコードはあなたが探しているもののようですが、自己参照や再帰はありません-指定された系統に沿ってツリーを通過し、系統の最後に指定されたカテゴリを挿入します。いくつかの仮定:

  • ツリーはそのルートのリストとして保存されます
  • 系統は文字列です

    void AddCategory(List<Category> roots, Category categoryToAdd, string lineage)
    {
        List<Guid> categoryIdList = lineage.Split('/').Select(id => new Guid(id)).ToList();
    
        List<Category> currentNodes = roots;
        Category parentNode = null;
    
        foreach (Guid categoryId in categoryIdList)
        {
            parentNode = currentNodes.Where(category => category.CategoryId == categoryId).Single();
            currentNodes = parentNode.Children;
        }
    
        parentNode.Children.Add(categoryToAdd);
    }
    
于 2012-08-01T12:30:16.950 に答える
0

「ref」はまったく必要ないようです。オブジェクト参照を変更するのではなく、その状態だけを変更します。

編集:refを使用する必要がある場合は、一時変数を使用します。たとえば、...

        foreach (var temp in parentCategory.Children)
        {
            Category category = temp;
            if (category.CategoryId == lastNode)
            {
                this.AddToTree(ref category, newCategory, lineage);
            }
        }

しかし、これでも、refはほとんど役に立たない。AddToTreeは参照値を変更しません。参照されるオブジェクトの状態を変更します。多分あなたは私たちが見る必要があるより多くのコードを含んでいます。

親の子参照を変更することを目的としている場合は、ICollectionChildrenオブジェクトに問題があります。ICollectionの要素で「ref」を使用して、実際に参照を置き換えることはできません。子参照を削除して、新しい参照を追加する必要があります。

于 2012-08-01T12:15:29.007 に答える