2009-03-15 24 views
15

क्या सी # में एक सामान्य प्रकार को परिभाषित करना संभव है जो संदर्भ खुद ही है?रिकर्सिव जेनेरिक प्रकार

उदा। मैं एक शब्दकोश <> को परिभाषित करना चाहता हूं जो इसके प्रकार को टीवीएयू (पदानुक्रम के लिए) के रूप में रखता है।

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

नहीं, यह संभव नहीं है। क्या आप जो हासिल करने की कोशिश कर रहे हैं उस पर आप अधिक विशिष्ट हो सकते हैं? –

+0

लॉल ईरविकियर, आपको यह मानना ​​होगा कि यह अजीब है;) ... मैंने यह भी सोचा कि यह नहीं (सीधे) .. – 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> { } सोचें।

संबंधित मुद्दे