まず、スキップリストのコンテナクラスはこんな感じだ。
public class SkipList<TItem, TNode>
where TItem:class
where TNode:SkipListNode<TItem, TNode>, new()
{
TNode header, footer;
public SkipList()
{
header=SkipListNode<TItem, TNode>.CreateHeader();
footer=SkipListNode<TItem, TNode>.CreateFooter();
...
}
public void Insert(TItem item){
...
TNode newNode=SkipListNode<TItem, TNode>.CreateNode(item);
}
}
んで、ノードクラスはこんな感じだ。
public class SkipListNode<TItem, TNode>
where TItem:class
where TNode:SkipListNode<TItem, TNode>, new()
{
private TNode thisNode;
private TItem item;
private bool isHeader, isFooter;
public static TNode CreateNode(TItem item)
{
TNode newNode=new TNode();
newNode.thisNode=newnode;
newNode.item=Item;
newNode.isHeader=false;
newNode.isFooter=false;
return newNode;
}
public static TNode CreateHeader()
{
TNode newNode=new TNode();
newNode.thisNode=newnode;
newNode.item=null;
newNode.isHeader=true;
newNode.isFooter=false;
return newNode;
}
public static TNode CreateFooter()
{
TNode newNode=new TNode();
newNode.thisNode=newnode;
newNode.item=null;
newNode.isHeader=false;
newNode.isFooter=true;
return newNode;
}
...
他のメソッド(TNode型での自身への参照が欲しければthisでなくthisNodeフィールドを使う)
...
バーチャルなメソッドとかバーチャルなプロパティとか
}
使い方としては、
MyNode:SkipListNode<MyItem, MyNode>{
オーバーライドしたりプロパティを追加したり
}
...
クラスの定義の中で
SkipList<MyItem, MyNode> myList=new SkipList<MyItem, MyNode>();
...
などと使う。
特に、SkipListNode<TItem, TNode>の定義中でthisと書くとその型はSkipListNode<TItem, TNode>型になり、TNode型にならないので、TNode型のthisNodeフィールドを用意する事で、実行時の余計なキャストが必要なくなる。さりげないがここ超重要。