Curiously Recurring Template Pattern and generics constraints (C#)

后端 未结 2 900
萌比男神i
萌比男神i 2020-11-28 13:20

I would like to create a method in a base generic class to return a specialized collection of derived objects and perform some operations on them, like in the following exam

2条回答
  •  余生分开走
    2020-11-28 13:38

    I have used the following to create not a linked list, but a generecic linked tree. It works wonderfully nicely.

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

    Example usage from Mechanics (Coordinate System Hierarchy)

    class Coord3 : Tree
    {
        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 );
           }
        }
    }
    

    The trick is to initialize the root object with null parent. Remember you cannot do Coord3() : base(this) { }.

提交回复
热议问题