2009-03-15 25 views
15

それ自体を参照するC#でジェネリック型を定義することはできますか?再帰ジェネリック型

など。そのタイプをTValue(階層の場合)として保持するDictionary <を定義したいと思います。

Dictionary<string, Dictionary<string, Dictionary<string, [...]>>> 
+0

いいえ、これはできません。あなたは達成しようとしているところでより具体的になりますか? –

+0

lol Earwicker、あなたはそれが変わっていると同意しなければならない;)...私もそれは(直接的に)... – eglasius

+0

だと思った。クラスがそれ自身から継承することができないので、人々は混乱するだろうと思う(明らかに、まもなくフィールドがあるように)、ジェネリックは型パラメータから継承することはできませんが、クラスの独自の名前と型のパラメータは、一般的な基底の型引数に現れるかもしれません。 –

答えて

41

試してみてください。

class StringToDictionary : Dictionary<string, StringToDictionary> { } 

次にあなたが書くことができます再帰ため

var stuff = new StringToDictionary 
     { 
      { "Fruit", new StringToDictionary 
       { 
        { "Apple", null }, 
        { "Banana", null }, 
        { "Lemon", new StringToDictionary { { "Sharp", null } } } 
       } 
      }, 
     }; 

一般原則:それが参照できるように、再帰的なパターンに名前を与えるためにいくつかの方法を見つけますそれ自体が名前で。

+0

+1、実際にコンパイル/実行 – eglasius

+0

ありがとう!良いその辞書は封印されていません:) – laktak

+4

勝利のためのラムダ計算! – data

7

別の例は、

public class CoordSys : Tree<CoordSys> 
{ 
    CoordSys() : base(null) { } 
    CoordSys(CoordSys parent) : base(parent) { } 
    public double LocalPosition { get; set; } 
    public double GlobalPosition { get { return IsRoot?LocalPosition:Parent.GlobalPosition+LocalPosition; } } 
    public static CoordSys NewRootCoordinate() { return new CoordSys(); } 
    public CoordSys NewChildCoordinate(double localPos) 
    { 
     return new CoordSys(this) { LocalPosition = localPos }; 
    } 
} 

static void Main() 
{ 
    // Make a coordinate tree: 
    // 
    //     +--[C:50] 
    // [A:0]---[B:100]--+   
    //     +--[D:80] 
    // 

    var A=CoordSys.NewRootCoordinate(); 
    var B=A.NewChildCoordinate(100); 
    var C=B.NewChildCoordinate(50); 
    var D=B.NewChildCoordinate(80); 

    Debug.WriteLine(C.GlobalPosition); // 100+50 = 150 
    Debug.WriteLine(D.GlobalPosition); // 100+80 = 180 
} 

にあなたが直接Tree<T>をインスタンス化することはできません注意をそれを使用するために今、一般的なツリー

public class Tree<T> where T : Tree<T> 
{ 
    public T Parent { get; private set; } 
    public List<T> Children { get; private set; } 
    public Tree(T parent) 
    { 
     this.Parent = parent; 
     this.Children = new List<T>(); 
     if(parent!=null) { parent.Children.Add(this); } 
    } 
    public bool IsRoot { get { return Parent == null; } } 
    public bool IsLeaf { get { return Children.Count==0; } } 
} 

だろう。これは、ツリー内のノードクラスの基本クラスでなければなりません。考えてくださいclass Node : Tree<Node> { }