Curiously Recurring Template Pattern and generics constraints (C#)
Solution 1:
This might work for you:
class Base<T> where T : Base<T>
You can't constrain T
to an open generic type. If you need to constrain T
to Base<whatever>
, you'll need to construct something like:
abstract class Base { }
class Base<T> : Base where T : Base { ... }
Solution 2:
I have used the following to create not a linked list, but a generic linked tree. It works wonderfully nicely.
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; } }
}
Example usage from Mechanics (Coordinate System Hierarchy)
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 );
}
}
}
The trick is to initialize the root object with null
parent. Remember you cannot do Coord3() : base(this) { }
.