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]