C#で循環リスト
通常のリストを循環リストにする。
/// <summary>
/// 循環リスト
/// </summary>
/// <typeparam name="T"></typeparam>
class InfiniteList<T> : IEnumerable<T>
{
private readonly List<T> _list;
public InfiniteList(IEnumerable<T> source)
{
_list = source.ToList();
}
public IEnumerator<T> GetEnumerator()
{
while (true)
{
foreach (T val in _list)
{
yield return val;
}
}
}
IEnumerator IEnumerable.GetEnumerator()
{
return this.GetEnumerator();
}
}
class Program
{
static void Main(string[] args)
{
// 単純な循環リスト
int[] a12345 = { 1, 2, 3, 4, 5 };
InfiniteList<int> infiniteInt = new InfiniteList<int>(a12345);
foreach(var x in infiniteInt.Take(20))
{
Console.WriteLine(x);
}
// ランダムな値を返す関数のリストにすればランダムな無限リストが得られる
var rnd = new Random();
Func<int>[] r = { () => rnd.Next() };
InfiniteList<Func<int>> infiniteFunc = new InfiniteList<Func<int>>(r);
foreach(var f in infiniteFunc.Take(20))
{
Console.WriteLine(f());
}
}
}
実行結果
1
2
3
4
5
1
2
3
4
5
1
2
3
4
5
1
2
3
4
5
1907137116
495422201
112043150
962297659
728376374
1593775114
1232326859
437976340
1500446889
1646938930
1574476665
1872560263
198735725
1398558555
917918457
3743234
1411914095
1404301363
2043674725
644393754
こんな感じの拡張メソッドを用意しておけばメソッドチェーンもできますね。
public static IEnumerable<T> Infinite<T>(this IEnumerable<T> source) =>
new InfiniteList<T>(source);