2009-08-25 5 views
10

मैं एक आधार सामान्य वर्ग में एक विधि बनाने के लिए निम्न उदाहरण में ली गई वस्तुओं की एक विशेष संग्रह लौट सकते हैं और उन पर कुछ कार्रवाई करने, की तरह चाहते हैं:मजे की बात है आवर्ती टेम्पलेट पैटर्न और जेनरिक की कमी (सी #)

using System; 
using System.Collections.Generic; 

namespace test { 

    class Base<T> { 

     public static List<T> DoSomething() { 
      List<T> objects = new List<T>(); 
      // fill the list somehow... 
      foreach (T t in objects) { 
       if (t.DoSomeTest()) { // error !!! 
        // ... 
       } 
      } 
      return objects; 
     } 

     public virtual bool DoSomeTest() { 
      return true; 
     } 

    } 

    class Derived : Base<Derived> { 
     public override bool DoSomeTest() { 
      // return a random bool value 
      return (0 == new Random().Next() % 2); 
     } 
    } 

    class Program { 
     static void Main(string[] args) { 
      List<Derived> list = Derived.DoSomething(); 
     } 
    } 
} 

मेरे समस्या यह है कि इस तरह के एक बात मैं

तरह की कोई समस्या
class Base<T> where T : Base { 
} 

यह है कि किसी तरह की तरह की कोई समस्या निर्दिष्ट करने के लिए संभव है निर्दिष्ट करने के लिए की आवश्यकता होगी करने के लिए है?

+0

इस तरह के कोड के लिए बेहतर भाषा समर्थन जोड़ने के लिए बस इस उपयोगकर्ताव्यापी सुझाव को बनाया गया है, इस पर वोट देने के लिए स्वतंत्र महसूस करें! https://visualstudio.uservoice.com/forums/121579-visual-studio-ide/suggestions/32188474-support-this-as-a-return-type-to-make-building-f –

उत्तर

22

यह आप के लिए काम कर सकते हैं:

class Base<T> where T : Base<T> 

आप एक खुला सामान्य प्रकार के T विवश नहीं कर सकते। आप Base<whatever> को T बाध्य करने की आवश्यकता है, तो आप की तरह कुछ का निर्माण करने की आवश्यकता होगी:

abstract class Base { } 

class Base<T> : Base where T : Base { ... } 
+0

बिल्कुल वही जो मैं चाहता था , धन्यवाद :) –

+2

वाह, यह कानूनी है? – Qwertie

+1

क्वर्टी: हाँ, क्यों नहीं? –

8

मैं एक लिंक्ड सूची नहीं बनाने के लिए निम्नलिखित का इस्तेमाल किया है, लेकिन एक generecic जुड़ा हुआ पेड़। यह अच्छी तरह से अच्छी तरह से काम करता है। यांत्रिकी से

public class Tree<T> where T : Tree<T> 
{ 
    T parent; 
    List<T> children; 

    public Tree(T parent) 
    { 
     this.parent = parent; 
     this.children = new List<T>(); 
     if(parent!=null) { parent.children.Add(this as T); } 
    } 
    public bool IsRoot { get { return parent == null; } } 
    public bool IsLeaf { get { return children.Count == 0; } } 
} 

उदाहरण उपयोग (निर्देशांक प्रणाली पदानुक्रम)

class Coord3 : Tree<Coord3> 
{ 
    Vector3 position; 
    Matrix3 rotation; 
    private Coord3() : this(Vector3.Zero, Matrix3.Identity) { } 
    private Coord3(Vector3 position, Matrix3 rotation) : base(null) 
    { 
     this.position = position; 
     this.rotation = rotation; 
    } 
    public Coord3(Coord3 parent, Vector3 position, Matrix3 rotation) 
     : base(parent) 
    { 
     this.position = position; 
     this.rotation = rotation; 
    } 
    public static readonly Coord3 World = new Coord3(); 

    public Coord3 ToGlobalCoordinate() 
    { 
     if(IsRoot) 
     { 
      return this; 
     } else { 
      Coord3 base_cs = parent.ToGlobalCoordinate(); 
      Vector3 global_pos = 
         base_cs.position + base_cs.rotation * this.position; 
      Matrix3 global_rot = base_cs.rotation * this.rotation; 
      return new Coord3(global_pos, global_ori); 
     } 
    } 
} 

चाल null माता पिता के साथ जड़ वस्तु को प्रारंभ करने के लिए है। याद रखें कि Coord3() : base(this) { } नहीं कर सकता है।

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