Ответ Джонатана прост и отлично подходит для небольших списков, но если данных, которые вам нужно сохранить, не 8, а гораздо больше (будущие требования), непрерывное смещение данных может оказаться дорогостоящим. Существует простой способ избежать этого, создав индивидуальную оболочку списка:
class FiniteWrapList<T>: IEnumerable<T>
{
private readonly List<T> innerList;
private int counter;
private readonly int capacity;
public static FiniteWrapList<T> CreateNew(int capacity)
=> new FiniteWrapList<T>(capacity);
private FiniteWrapList(int capacity)
{
this.capacity = capacity;
innerList = new List<T>(capacity);
}
public void Add(T t)
{
if (counter >= capacity)
{
innerList[counter % capacity] = t;
}
else
innerList.Add(t);
counter = counter % (2 * capacity) + 1;
}
public T this[int index]
{
get => innerList[(counter + index) % capacity];
}
public IEnumerator<T> GetEnumerator()
{
if (counter < capacity)
return innerList.GetEnumerator();
return GetWrappedListEnumerator();
IEnumerator<T> GetWrappedListEnumerator()
{
for (var i = 0; i < capacity; i++)
yield return innerList[(counter + i) % capacity];
}
}
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
}
Таким образом вы избежите беспорядка с перемещением данных внутри списка. Вы просто создаете интеллектуальный индексатор и используете единый список, в котором просто перезаписываете старые данные.