C# 在复杂对象列表之间迭代
我使用此代码在类的实例之间移动C# 在复杂对象列表之间迭代,c#,C#,我使用此代码在类的实例之间移动 public class Orders : List<Order> { int currentIndex = 0; public int CurrentIndex { get { if (currentIndex == Count) { currentIndex = 0; } else if (currentIndex >
public class Orders : List<Order>
{
int currentIndex = 0;
public int CurrentIndex {
get {
if (currentIndex == Count) {
currentIndex = 0;
} else if (currentIndex > Count - 1) {
currentIndex = Count - 1;
} else if (currentIndex < 0) {
currentIndex = 0;
}
return currentIndex;
}
set { currentIndex = value; }
}
public void MoveNext()
{
currentIndex++;
}
public void MovePrevious()
{
currentIndex--;
}
public Order Current {
get {
return this[CurrentIndex];
}
}
}
public class Cart
{
public string id_ordine { get; set; }
public string nome { get; set; }
public string cognome { get; set; }
public double prezzo { get; set; }
}
我会采取完全不同的方法。一个项目列表中自然没有“游标”——能够有多个游标是完全合乎逻辑的,就像一本书中有多个书签一样 对于列表本身,我将坚持使用
列表
,但使用GetIndexedEnumerator()
扩展方法(可能在IList
上)创建一个IndexedListEnumerator
类型或类似的东西。这将实现IEnumerator
,但也有一个MovePrevious()
方法和一个Index
属性
这将“我想要一个更灵活的光标”与“我想要一个订单列表”区分开来
我还强烈建议,除非您真的、真的需要您当前拥有的那种“环绕”功能,否则您应该将索引设置为一个简单的属性,但在尝试访问无效索引时,将Current
设置为抛出异常。(因此,初始索引将为-1,Current
将无效。调用MoveNext()
会将您带到索引0,该索引对任何非空列表都有效,等等)作为一个草图:
public static class ListExtensions
{
public static IndexedListEnumerator<T> GetIndexedListEnumerator<T>(this IList<T> list) =>
new IndexedListEnumerator<T>(list);
}
public sealed class IndexedListEnumerator<T> : IEnumerator<T>
{
private readonly IList<T> list;
// You *could* restrict this to the range [-1, list.Count] if you wanted.
public int Index { get; set; }
// You might want to make this public
private bool IndexIsValid => Index >= 0 && Index < list.Count;
public IndexedListEnumerator(IList<T> list)
{
this.list = list;
Index = -1; // Before the first element
}
// TODO: Consider using checked to throw an exception around int.MaxValue
public bool MoveNext()
{
Index++;
return IndexIsValid;
}
public bool MovePrevious()
{
Index--;
return IndexIsValid;
}
public T Current => list[Index];
object IEnumerator.Current => Current;
void IDisposable.Dispose() {}
void IEnumerator.Reset() => Index = -1;
}
你能把你试过的贴出来吗?要在后面的代码中访问ordersList,您应该像
order.ordersList
一样编写(order类的给定对象名为order)。要循环使用它,您可以编写类似于foreach(var order in order.ordersList)
的代码,作为旁白,我强烈建议您遵循.NET属性命名约定。这将减少任何习惯于阅读你的代码的人之间的摩擦。你有一些糟糕的类命名。为什么OrdersList
只是一个具有两个基本属性的对象?这不是“订单”或“列表”。嗨,Daisy thx,这是一个很好的解决方案,但我不确定从我的案例来看,这是否合适,因为通常情况下有1个订单和多个订单列表,所以问题是迭代beltween订单列表而不是订单。那么我能把这个应用到订单单上吗?@andymo:恐怕我根本不明白你的意思。请注意,使用我的解决方案,您可以轻松地在列表上调用getIndexedListNumerator()
。(我想指出,OrdersList
是一个奇怪的名称,它看起来像是一个单一的项目,请注意。)如果你能更清楚地说明你想要实现的目标,这会有所帮助。我已经用有限的信息给出了最好的答案,但在问题有点不清楚的情况下,我们只能做这么多。这可能是一个错误的命名解决方案。:-)这是我的顾客送来的。无论如何,考虑这个1阶-->多阶列表>Daisy@andymo如果你的客户做出奇怪的命名选择,我会把它当作你可以提供的值的一部分。如果你认为他们的建议是错误的,就不要随波逐流。@andymo:而且“考虑一下这1个订单-->多个订单列表”并没有告诉我你想用它做什么,或者我的代码在什么方面帮不了你。请花一点时间清楚地表达你想要实现的目标,并将其编辑到问题中。
order orderslist
-------------+-----------------
name surname id_ordine prezzo
-------------+-----------------
john doe --> 1 10
--> 2 12
--> 3 22
public static class ListExtensions
{
public static IndexedListEnumerator<T> GetIndexedListEnumerator<T>(this IList<T> list) =>
new IndexedListEnumerator<T>(list);
}
public sealed class IndexedListEnumerator<T> : IEnumerator<T>
{
private readonly IList<T> list;
// You *could* restrict this to the range [-1, list.Count] if you wanted.
public int Index { get; set; }
// You might want to make this public
private bool IndexIsValid => Index >= 0 && Index < list.Count;
public IndexedListEnumerator(IList<T> list)
{
this.list = list;
Index = -1; // Before the first element
}
// TODO: Consider using checked to throw an exception around int.MaxValue
public bool MoveNext()
{
Index++;
return IndexIsValid;
}
public bool MovePrevious()
{
Index--;
return IndexIsValid;
}
public T Current => list[Index];
object IEnumerator.Current => Current;
void IDisposable.Dispose() {}
void IEnumerator.Reset() => Index = -1;
}
List<Order> orders = ...;
var enumerator = orders.GetIndexedListEnumerator();
enumerator.Index = 10;
Console.WriteLine(enumerator.Current); // Prints orders[10]
enumerator.MovePrevious();
Console.WriteLine(enumerator.Current); // Prints orders[9]
enumerator.MoveNext();
enumerator.MoveNext();
Console.WriteLine(enumerator.Current); // Prints orders[11]