2016-10-17 9 views
2

C#で型保護されたツリーの実装を実装するために/ tringを探しています。のC#で型安全なツリーの実装(型保証されたノード)

インターフェイスを使用せずにタイプセーフなツリーを実装するにはどうすればいいですか(キャストを使わずにツリー機能を全面的に再実装する必要があります)?

私はツリーを共通の基底クラスとして使用する考えがありますが、型の安全はなくなりました。私の現在のアプローチは、使用法ジェネリックスです。しかし、私はベースタイプに戻っていくつかの変換が欠けている。

以下は、縮小/非動作の例です。 考えられるのは、返されたノードがツリー関数をサポートしていると同時に、それらが基本型の動作をサポートしているということです。 Nodeクラスを継承しないで、以下のクラスを使用することもできますが、一方で型の安全性を失い、継承に問題が発生します。

私もクラス拡張でうんざりしていましたが、可能な解決策に近いものはありませんでした。

私は、どのように続けるかについての小さなヒントが必要だと思います。前もって感謝します。

public class Node<T> // . 
{ 
    public Node<T> parent; 
    public List<Node<T>> children; 

    protected Node() 
    { 
     children = new List<Node<T>>(); 
     parent = null; 
    } 
    protected Node(Node<T> parent) 
     : this() 
    { 

     this.parent = parent; 
     parent.addChildren(this); 
    } 


    protected void addChildren(Node<T> child) 
    { 
     children.Add(child); 
    } 
    public Node<T> getRoot() // returns root node 
    public List<Node<T>> flatten() // return 1d-list of all nodes. 

} 
+0

Tのタイプはツリー内のノードごとに異なることはありますか?それとも、それは木全体で常に同じでしょうか? – Soukai

+0

いいえ(サブクラスのみ)。しかし、私は別のTのために同じツリーの実装を使用したいと思います。 – James

答えて

0

は、タイプセーフなツリーの実装です:

public class Tree<T> : List<Tree<T>> 
{ 
    public T Value { get; set; } 
} 

はい、それはそれです。シンプル。

もちろん、1つまたは2つのコンストラクタを追加して、Valueプロパティを読み取り専用にして、OOPにやさしくすることができます。そして簡単にParentプロパティを追加することができます。

+0

ベストアイデアは明らかです。 :-) – James

0

は、私は木のような共通の基本クラスを使用してのアイデアを持っているが、その後、安全性がなくなって入力します。私の現在のアプローチは、使用法ジェネリックスです。しかし、私はベースタイプに戻っていくつかの変換が欠けている。

その後、あなたの基本型にジェネリック型を制約:

public class Node<T> where T: BaseType { ... } 

は今、あなたは限りMyDerivedTypeBaseTypeから派生したタイプNode<MyDerivedType>のいずれかのツリーを作成することができます。側では

ない、私はあなたの実装に次のように変更することを検討したい:

  1. Childrenその読み取り専用しない限り、フィールドを公開していない、プロパティでなければなりません。さらに、Listとして公開しないでください。誰もあなたの実装で想定されている不変条件に違反する可能性のあるノードを直接追加または削除することができます。代わりにIEnumerable<T>を返します:

    private readonly List<T> children; 
    public IEnumerable<T> Children => children.Select(c => c); 
    

    あなたはIEnumerable<T>への暗黙的に変換として直接childrenを返すことができます。問題は誰でも簡単にList<T>にキャストして変更できることです。それを投影することで、この変換からあなたを守ることができます。

  2. 同じことがFlattenで起こります(最初のfはbtwで大文字にする必要があります)。 IEnumerable<T>も返すことを検討してください。ここで

関連する問題