C#で循環リストのようなデータ構造を実現したい

実現したいこと

ループ形状の図の線上にいくつかの点を打ったものを扱うツールを開発しています。
適当な点を原点とし、原点から線を辿った距離を一次元の座標値として点の位置を表現しています。

順番に点を見ていったり、隣接する点を取得したりといった操作をするので、
循環リストのようなものを作れば便利では無いかと考えました。
また、foreachで回せて、どんな順で点を登録しても自動で順に並ぶとより都合が良いと思い、
SortedListを継承してCircularListという自作クラスを実装してみたのですが、
不便さの残る結果となってしまったのでアドバイス頂きたいです。

発生している問題・エラーメッセージ

下記にソースコードを示します。
ある程度思っていた動作はするのですが、
foreach文で回すとその都度Reset()関数を呼ばないとインデックス値が初期化されない、
SortedListベースであるため同じ座標値を登録すると重複で例外が発生してしまうなど微妙な結果となりました。
より良い循環リストの実装方法、もしくは循環リスト以外のより良いアプローチがあればご教示頂きたいです。

該当のソースコード

C#

1public class CircularList<TKey, TValue> : SortedList<TKey, TValue>, IEnumerator<KeyValuePair<TKey, TValue>>2 {3 /// <summary>4 /// 循環する整列済みリスト5 /// foreachでは原点から一周する(原点は初期値は0で変更可能)6 /// </summary>7 /// <returns></returns>8 9 private int originIndex;10 private int currentIndex;11 private int numberOfCall;12 private bool firstFlag;13 14 public CircularList()15 {16 this.originIndex = 0;17 this.currentIndex = -1;18 this.numberOfCall = 0;19 this.firstFlag = true;20 }21 22 public CircularList(IComparer<TKey> comparer) : base(comparer)23 {24 this.originIndex = 0;25 this.currentIndex = -1;26 this.numberOfCall = 0;27 this.firstFlag = true;28 }29 30 public int OriginIndex 31 {32 get { return this.originIndex; }33 set { this.originIndex = value; }34 }35 36 public void SetOriginIndex()37 {38 this.originIndex = (this.currentIndex + 1) % this.Count;39 }40 public new IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator()41 {42 return this;43 }44 public KeyValuePair<TKey, TValue> Current 45 {46 get { return new KeyValuePair<TKey, TValue>(this.Keys[this.currentIndex], this.Values[this.currentIndex]); }47 }48 object System.Collections.IEnumerator.Current 49 {50 get { return this; }51 }52 public bool MoveNext()53 {54 55 if (this.Count > 0)56 {57 this.currentIndex++;58 this.currentIndex %= this.Count;59 this.numberOfCall = 0;60 }61 62 if (this.currentIndex == this.originIndex && !firstFlag)63 {64 this.currentIndex--;65 if (this.currentIndex < 0)66 {67 this.currentIndex = this.Count - 1;68 }69 firstFlag = true;70 return false;71 }72 73 firstFlag = false;74 75 return true;76 }77 public void Reset()78 {79 this.currentIndex = this.originIndex - 1;80 if (this.currentIndex < 0)81 {82 this.currentIndex = this.Count - 1;83 }84 firstFlag = true;85 }86 public void Dispose()87 {88 89 }90 91 public KeyValuePair<TKey, TValue> GetNextPair()92 {93 this.numberOfCall++;94 int nextIndex = (this.currentIndex + this.numberOfCall) % this.Count;95 return new KeyValuePair<TKey, TValue>(this.Keys[nextIndex], this.Values[nextIndex]);96 }97 98 public void ChangeKey(TKey oldKey, TKey newKey)99 {100 TValue value = this[oldKey];101 this.Remove(oldKey);102 this[newKey] = value;103 }104 }

コメントを投稿

0 コメント