3

私はツリーをフォルダ構造と考えて実装しているので、次のようなクラスがあります。

public class Folder
{
    //Various Props like Name etc.
    public IList<Folder> Children{get;}
    public Folder Parent {get;}
}

今私が望むのは、ツリーを上下に移動できるようにすることです。これにより、ルートが与えられれば葉を見つけることができ、葉が与えられればルートノードを見つけることができます。したがって、子供にはそれぞれ親が必要です。問題は、新しいノードをツリーに追加する最良の方法は何かということです。過去に2つのソリューションを使用しました。

  1. フォルダーの追加を処理し、親を設定できる AddChild(Folder) メソッドを Folder に追加します。これに関する問題は、このメソッドをバイパスできないように、 Children コレクションをロックする必要があることです。
  2. インスタンスへの参照が与えられる独自の Children コレクションを作成して、追加時に親の設定を処理できるようにします。これに関する問題は、新しいコレクションを実装する必要があります。
  3. アイテムが追加または削除されたときにイベントを持つコレクションを使用します。

人々が一般的にどのようなパターンを使用しているか、そして私の特定のユースケースについて何か提案があるかどうかに興味があります。nHibernate を使用してツリーを SQL サーバーに永続化しています。アプリケーションの非常に小さな部分である何かに対してこれを機能させるには多くのコードがあるため、カスタムコレクションを実装したくありません。

4

5 に答える 5

3

MSDNを見た後、これを試すことができます:

List<Folder> children;

public ReadOnlyCollection<Folder> Children
{
    get { return this.children.AsReadOnly(); }
}

プライベート メンバーを IList として宣言する必要がある場合は、それをリストにコピーして返すことができます。しかし、具体的な実装をプライベートメンバーとして使用することに問題はありません。後で実装を変更しても、互換性が失われることはありません。

IList<Folder> children;

public ReadOnlyCollection<Folder> Children
{
    get 
    { 
        return new List<Folder>(this.children).AsReadOnly(); 
    }
}
于 2009-01-13T16:57:19.470 に答える
1

個人的には、方法 1 を使用します。クライアント コードが Children コレクションを操作できるようにすることは、いずれの場合もカプセル化に直接違反するため、Children コレクションを「ロック」することは正しいことです。

ノード関係を正しく維持するための「適切な」戦略は、クライアントのニーズによって異なります。この特定の状況では、クライアントが子ノード自体を変更できるようにしたいが、 Children コレクションは変更できないと思います。その場合、Rob Prouse の提案 (Children プロパティが IEnumerable を返すようにする) がおそらく最良の選択だと思います。他の状況では、おそらく ReadOnlyCollection の方が適しています。

于 2009-01-13T16:37:46.203 に答える
1

オプション 1 を使用して、Children プロパティを次のようにします。

    public IEnumerable<Folder> Children
    {
        get { return this.children.GetEnumerator(); }
    }

ここで、AddChild を呼び出して子を追加する必要があります。コレクションにアクセスできません。

于 2009-01-13T16:40:15.700 に答える
1

番号 1 を使用しますが、Children プロパティを IEnumerable にして、ユーザーがコレクションに追加できないようにします。

于 2009-01-13T16:43:49.543 に答える
1

カスタム コレクションの実装には多くの作業が必要です。2 つまたは 3 つのメソッドのみを公開する既存のコレクション クラスにラッパーを実装することはできません。JayArr への返信から判断すると、それがあなたが探しているもののようです。何かのようなもの:

public class ChildCollection
{
   // _Children is maintained by the Folder class, hence the internal access specifier
   internal Dictionary<KeyType, Folder> _Children = new Dictionary<KeyType, Folder>;

   public this[KeyType key]
   {
      get
      {
          return _Children[key];
      }
   }

   public IEnumerable<KeyType> Keys
   {
      get
      {
         return _Children.Keys;
      }
   }
}
于 2009-01-13T18:02:59.010 に答える