From 334accd070546ab818f2cbb69c756a795bc5d7e6 Mon Sep 17 00:00:00 2001 From: yyc12345 Date: Tue, 18 Nov 2025 21:56:50 +0800 Subject: [PATCH] feat: use new IEnumeratable type --- .../Utils/CountableEnumerable.cs | 64 +++++++++++++++++++ BallanceTasEditor/Utils/TasStorage.cs | 14 ++-- .../Utils/TasStorageTests.cs | 32 ++++++---- 3 files changed, 91 insertions(+), 19 deletions(-) create mode 100644 BallanceTasEditor/Utils/CountableEnumerable.cs diff --git a/BallanceTasEditor/Utils/CountableEnumerable.cs b/BallanceTasEditor/Utils/CountableEnumerable.cs new file mode 100644 index 0000000..9549dfb --- /dev/null +++ b/BallanceTasEditor/Utils/CountableEnumerable.cs @@ -0,0 +1,64 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BallanceTasEditor.Utils { + /// + /// 一种提前给定元素个数的的IEnumerable。 + /// + public sealed class CountableEnumerable { + /// + /// 以直接方式构建。 + /// + /// 一个迭代器,其最多只能迭代给定次数。 + /// 迭代器会迭代的次数。 + public CountableEnumerable(IEnumerable enumerable, int count) { + m_Inner = enumerable; + m_Count = count; + } + + /// + /// 从数组便捷构建。 + /// + /// 要使用的数组。 + public CountableEnumerable(T[] array) { + m_Inner = array; + m_Count = array.Length; + } + + private IEnumerable m_Inner; + private int m_Count; + + /// + /// 获取迭代器对象。 + /// + /// 用于迭代的迭代器。 + /// 当迭代器迭代次数与给定次数不匹配时。 + public IEnumerable GetInner() { + int counter = 0; + foreach (var item in m_Inner) { + if (counter >= m_Count) { + throw new ArgumentException("Given IEnumerable is not stopped at given count."); + } else { + yield return item; + ++counter; + } + } + + if (counter != m_Count) { + throw new ArgumentException("Given IEnumerable is not stopped at given count."); + } + } + + /// + /// 获取该迭代器会迭代的次数。 + /// + /// 迭代器会迭代的次数,用于给使用该结构的方法提前分配必要的空间。 + public int GetCount() { + return m_Count; + } + + } +} diff --git a/BallanceTasEditor/Utils/TasStorage.cs b/BallanceTasEditor/Utils/TasStorage.cs index 4b07531..e4a11a6 100644 --- a/BallanceTasEditor/Utils/TasStorage.cs +++ b/BallanceTasEditor/Utils/TasStorage.cs @@ -30,7 +30,7 @@ namespace BallanceTasEditor.Utils { /// 要在前方插入数据的元素的索引。 /// 要插入的元素的迭代器。 /// 给定的索引超出范围。 - void Insert(int index, IEnumerable items); + void Insert(int index, CountableEnumerable items); /// /// 从给定单元开始,移除给定个数的元素。 /// @@ -70,7 +70,7 @@ namespace BallanceTasEditor.Utils { throw new NotImplementedException(); } - public void Insert(int index, IEnumerable items) { + public void Insert(int index, CountableEnumerable items) { throw new NotImplementedException(); } @@ -108,8 +108,8 @@ namespace BallanceTasEditor.Utils { return m_Container[index]; } - public void Insert(int index, IEnumerable items) { - m_Container.InsertRange(index, items); + public void Insert(int index, CountableEnumerable items) { + m_Container.InsertRange(index, items.GetInner()); } public void Remove(int index, int count) { @@ -219,11 +219,11 @@ namespace BallanceTasEditor.Utils { } } - public void Insert(int index, IEnumerable items) { + public void Insert(int index, CountableEnumerable items) { if (index < 0 || index > GetCount()) { throw new ArgumentOutOfRangeException("Index out of range."); } else if (index == GetCount()) { - foreach (T item in items) { + foreach (T item in items.GetInner()) { m_Container.AddLast(item); } @@ -234,7 +234,7 @@ namespace BallanceTasEditor.Utils { MoveToIndex(index); int count = 0; - foreach (T item in items) { + foreach (T item in items.GetInner()) { m_Container.AddBefore(m_Cursor, item); ++count; } diff --git a/BallanceTasEditorTests/Utils/TasStorageTests.cs b/BallanceTasEditorTests/Utils/TasStorageTests.cs index 2aab09d..a46a9b6 100644 --- a/BallanceTasEditorTests/Utils/TasStorageTests.cs +++ b/BallanceTasEditorTests/Utils/TasStorageTests.cs @@ -13,6 +13,14 @@ namespace BallanceTasEditorTests.Utils { private static readonly int[] BLANK = { }; private static readonly int[] PROBE = { 10, 20, 30, 40, 50 }; + private static CountableEnumerable GetCountableProbe() { + return new CountableEnumerable(PROBE); + } + + private static CountableEnumerable GetCountableBlank() { + return new CountableEnumerable(BLANK); + } + private static IEnumerable TasStorageInstanceProvider { get { yield return new object[] { new ListTasStorage() }; @@ -34,7 +42,7 @@ namespace BallanceTasEditorTests.Utils { AssertExtension.ThrowsDerivedException(() => storage.Visit(1)); // 设置数据 - storage.Insert(0, PROBE); + storage.Insert(0, GetCountableProbe()); // 访问数据 AssertExtension.ThrowsDerivedException(() => storage.Visit(-1)); for (int i = 0; i < PROBE.Length; i++) { @@ -53,9 +61,9 @@ namespace BallanceTasEditorTests.Utils { // 和在非空时的头,中,尾分别插入的结果。 // 先检测空插入 - AssertExtension.ThrowsDerivedException(() => storage.Insert(-1, PROBE)); - AssertExtension.ThrowsDerivedException(() => storage.Insert(1, PROBE)); - storage.Insert(0, PROBE); + AssertExtension.ThrowsDerivedException(() => storage.Insert(-1, GetCountableProbe())); + AssertExtension.ThrowsDerivedException(() => storage.Insert(1, GetCountableProbe())); + storage.Insert(0, GetCountableProbe()); for (int i = 0; i < PROBE.Length; i++) { Assert.AreEqual(storage.Visit(i), PROBE[i]); } @@ -65,8 +73,8 @@ namespace BallanceTasEditorTests.Utils { foreach (var index in indices) { // 清空,一次插入,然后二次插入 storage.Clear(); - storage.Insert(0, PROBE); - storage.Insert(index, PROBE); + storage.Insert(0, GetCountableProbe()); + storage.Insert(index, GetCountableProbe()); // 用List做正确模拟 var expected = new List(); @@ -96,7 +104,7 @@ namespace BallanceTasEditorTests.Utils { foreach (var index in indices) { // 清空,插入,删除 storage.Clear(); - storage.Insert(0, PROBE); + storage.Insert(0, GetCountableProbe()); storage.Remove(index, 1); // 用List做正确模拟 @@ -119,7 +127,7 @@ namespace BallanceTasEditorTests.Utils { [DynamicData(nameof(TasStorageInstanceProvider))] public void ClearTest(ITasStorage storage) { // 设置数据后清空 - storage.Insert(0, PROBE); + storage.Insert(0, GetCountableProbe()); storage.Clear(); // 检查是否为空 @@ -136,7 +144,7 @@ namespace BallanceTasEditorTests.Utils { Assert.IsTrue(storage.IsEmpty()); // 插入数据后再检查 - storage.Insert(0, PROBE); + storage.Insert(0, GetCountableProbe()); Assert.IsFalse(storage.IsEmpty()); } @@ -150,7 +158,7 @@ namespace BallanceTasEditorTests.Utils { Assert.AreEqual(storage.GetCount(), 0); // 插入数据后再检查 - storage.Insert(0, PROBE); + storage.Insert(0, GetCountableProbe()); Assert.AreEqual(storage.GetCount(), PROBE.Length); } @@ -166,7 +174,7 @@ namespace BallanceTasEditorTests.Utils { Assert.AreEqual(storage.GetCount(), 0); // 设置内容 - storage.Insert(0, PROBE); + storage.Insert(0, GetCountableProbe()); // 并再次检查大小 Assert.IsFalse(storage.IsEmpty()); Assert.AreEqual(storage.GetCount(), PROBE.Length); @@ -185,7 +193,7 @@ namespace BallanceTasEditorTests.Utils { // 清空后插入0项,然后确认 storage.Clear(); - storage.Insert(0, BLANK); + storage.Insert(0, GetCountableBlank()); AssertExtension.ThrowsDerivedException(() => storage.Visit(-1)); AssertExtension.ThrowsDerivedException(() => storage.Visit(0)); AssertExtension.ThrowsDerivedException(() => storage.Visit(1));