C# 如何获取枚举器列表的下一个和上一个值?

C# 如何获取枚举器列表的下一个和上一个值?,c#,.net,C#,.net,当我试图在枚举器列表的while循环时,如何获取下一个和上一个值。请查找下面的代码 public static void Main() { List<string> mylist = new List<string>(); mylist.Add("C#"); mylist.Add("Java"); mylist.Add("C"); mylist.Add("C++"); // To get an Enumer

当我试图在枚举器列表的while循环时,如何获取下一个和上一个值。请查找下面的代码

public static void Main() 
{ 

    List<string> mylist = new List<string>(); 
    mylist.Add("C#"); 
    mylist.Add("Java"); 
    mylist.Add("C"); 
    mylist.Add("C++"); 

    // To get an Enumerator 
    // for the List. 
    List<string>.Enumerator em = mylist.GetEnumerator(); 
    display(em); 
} 

static void display(IEnumerator<string> em) 
{ 
    while (em.MoveNext()) { 
        string val = em.Current; // Want to know Next and Previous values of current value.


        Console.WriteLine(val); 
    } 
}
publicstaticvoidmain()
{ 
List mylist=新列表();
mylist.Add(“C#”);
添加(“Java”);
mylist.添加(“C”);
添加(“C++”);
//获取枚举数
//为了名单。
List.Enumerator em=mylist.GetEnumerator();
显示器(em);
} 
静态空白显示(IEnumerator em)
{ 
而(em.MoveNext()){
string val=em.Current;//想知道当前值的下一个和上一个值。
控制台写入线(val);
} 
}

枚举数,在
GetEnumerator()
意义下,仅向前,一次仅为数据上的游标。如果您想知道下一个值:使用
MoveNext()
并查看。如果你想知道前一个值是什么:你应该记住它。由于大多数数据结构都不是双链表,而且由于枚举数甚至不一定基于存储在任何地方的数据(您可以使用迭代器块做一些真正有趣的事情),所以其他一切都是不可能的

List
的特定情况下:可能使用
for
循环,而不是像
foreach
一样的枚举器访问,然后您可以使用
List[i-1]
List[i+1]
(检查边界条件后)


注意:一般来说,除非您非常非常熟悉下面的情况,否则应该避免直接使用枚举器API。首选
foreach
或基于索引器的访问


您可以使用自己的迭代器块来泛化三元组(previous/current/next)迭代器;
{1,4,5,1543,2,1,54,23}的输出

是:

代码:

使用系统;
使用System.Collections.Generic;
公共静态类程序
{
静态void Main()
{
var数据=新列表{1,4,5,1543,2,1,54,23};
foreach(data.Tripletize()中的var t)
{
WriteLine($“{t.Previous}-{t.Current}-{t.Next}”);
}
}
静态IEnumerable三重化(此IEnumerable源)
{
使用(var iter=source.GetEnumerator())
{
//读第一个三元组
如果(!iter.MoveNext())产生中断;
var x=iter.电流;
如果(!iter.MoveNext())产生中断;
var y=额定电流;
如果(!iter.MoveNext())产生中断;
var z=iter.电流;
产量-收益新三联体(x,y,z);
while(iter.MoveNext())
{
x=y;
y=z;
z=iter电流;
产量-收益新三联体(x,y,z);
}
}
}
只读结构三元组
{
公共三元组(T上一个、T当前、T下一个)
{
先前=先前;
电流=电流;
下一个=下一个;
}
公共T上一个{get;}
公共T当前{get;}
公共T下一个{get;}
}
}

IEnumerable
不支持检查上一项和下一项。它仅提供对当前项目的访问。如果要跟踪上一项,应将其手动存储在局部变量中。或者,您应该存储前两个值,并假设当前值是下一个值

static void display(IEnumerator<string> em)
{
    if (!em.MoveNext())
       return;

    string prev = null; // store prev
    string current = null; // store current
    string next = em.Current; // null <- null -> next

    do
    {
        // move 'window' further so that next becomes current            
        prev = current;
        current = next;
        next = em.MoveNext() ? em.Current : null;
        Console.WriteLine($"[{prev}] <-[{current}]-> [{next}]");
    }
    while (next != null);
}
静态无效显示(IEnumerator em)
{
如果(!em.MoveNext())
返回;
字符串prev=null;//存储prev
字符串current=null;//存储当前值
string next=em.Current;//null next
做
{
//进一步移动“窗口”,使下一个窗口成为当前窗口
prev=当前值;
当前=下一个;
next=em.MoveNext()?em.Current:null;
Console.WriteLine($“[{prev}][{next}]”;
}
while(next!=null);
}
输出测试数据:

"[] <-[C#]-> [Java]"
"[C#] <-[Java]-> [C]"
"]Java] <-[C]-> [C++]"
"[C] <-[C++]-> []"
“[[Java]”
“[C][C]”
“]Java][C++]”
“[C][]”

但有一种数据类型具有框中所需的功能-

var mylist=newlinkedlist();//而不是列表
mylist.AddLast(“C#”);
AddLast(“Java”);
mylist.AddLast(“C”);
AddLast(“C++”);
显示(mylist);
给你

static void display(LinkedList<string> list) 
{
    var current = list.First;
    while (current != null)
    {

        string val = current.Value;
        // null if there is no next/prev value, but you can just check if node exists
        string prev = current.Previous?.Value;
        string next = current.Next?.Value;

        Console.WriteLine(val);
        current = current.Next;
    } 
}
静态无效显示(LinkedList列表)
{
var电流=列表。第一;
while(当前!=null)
{
字符串val=当前的.Value;
//如果没有下一个/上一个值,则为null,但您可以只检查节点是否存在
字符串prev=当前.Previous?值;
字符串next=当前.next?值;
控制台写入线(val);
当前=当前。下一步;
} 
}

使用类似以下内容:

  class Program
    {
        int position = -1;

        public List<string> mylist;

        public bool MoveNext()
        {
            position++;
            return (position < mylist.Count);
        }

        public String GetCurrent
        {
            get
            {
                return Current;
            }
        }

        public string GetPrevious
        {
            get
            {
                return Previous;
            }
        }

        public String Previous
        {
            get
            {
                try
                {
                    return mylist[position-1];
                }
                catch (IndexOutOfRangeException)
                {
                    throw new InvalidOperationException();
                }
            }
        }


        public String Current
        {
            get
            {
                try
                {
                    return mylist[position];
                }
                catch (IndexOutOfRangeException)
                {
                    throw new InvalidOperationException();
                }
            }
        }


        void Main(string[] args)
        {

            mylist = new List<string>();
            mylist.Add("C#");
            mylist.Add("Java");
            mylist.Add("C");
            mylist.Add("C++");


            display(mylist);
        }

        void display(List<string> em)
        {
            while (MoveNext())
            {
                string val = GetCurrent;
                string val2 = GetPrevious;
                Console.WriteLine(val);
            }
        }
}
类程序
{
int位置=-1;
公开名单;
公共图书馆
{
位置++;
返回(位置<我的列表计数);
}
公共字符串GetCurrent
{
得到
{
回流;
}
}
公共字符串GetPrevious
{
得到
{
返回上一个;
}
}
前一个公共字符串
{
得到
{
尝试
{
返回mylist[位置-1];
}
捕获(IndexOutOfRangeException)
{
抛出新的InvalidOperationException();
}
}
}
公共字符串电流
{
得到
{
尝试
{
返回mylist[位置];
}
捕获(IndexOutOfRangeException)
{
抛出新的InvalidOperationException();
}
}
}
void Main(字符串[]args)
{
mylist=新列表();
mylist.Add(“C#”);
static void display(LinkedList<string> list) 
{
    var current = list.First;
    while (current != null)
    {

        string val = current.Value;
        // null if there is no next/prev value, but you can just check if node exists
        string prev = current.Previous?.Value;
        string next = current.Next?.Value;

        Console.WriteLine(val);
        current = current.Next;
    } 
}
  class Program
    {
        int position = -1;

        public List<string> mylist;

        public bool MoveNext()
        {
            position++;
            return (position < mylist.Count);
        }

        public String GetCurrent
        {
            get
            {
                return Current;
            }
        }

        public string GetPrevious
        {
            get
            {
                return Previous;
            }
        }

        public String Previous
        {
            get
            {
                try
                {
                    return mylist[position-1];
                }
                catch (IndexOutOfRangeException)
                {
                    throw new InvalidOperationException();
                }
            }
        }


        public String Current
        {
            get
            {
                try
                {
                    return mylist[position];
                }
                catch (IndexOutOfRangeException)
                {
                    throw new InvalidOperationException();
                }
            }
        }


        void Main(string[] args)
        {

            mylist = new List<string>();
            mylist.Add("C#");
            mylist.Add("Java");
            mylist.Add("C");
            mylist.Add("C++");


            display(mylist);
        }

        void display(List<string> em)
        {
            while (MoveNext())
            {
                string val = GetCurrent;
                string val2 = GetPrevious;
                Console.WriteLine(val);
            }
        }
}