Изменение порядка Foreach?

Есть ли так или иначе к foreach через список от конца до начала, а не начала затем закончиться (предпочтительно, не переупорядочивая список).

10
задан sooprise 23 July 2010 в 17:44
поделиться

7 ответов

using System.Linq;

foreach(var item in source.Reverse())
{
    ...
}

Изменить: Есть еще один шаг, если вы имеете дело конкретно с List . Этот класс определяет свой собственный метод Reverse , сигнатура которого не такая же, как у метода расширения Enumerable.Reverse . В этом случае вам нужно «поднять» ссылку на переменную на IEnumerable :

using System.Linq;

foreach(var item in list.AsEnumerable().Reverse())
{
    ...
}
36
ответ дан 3 December 2019 в 13:24
поделиться

вы могли бы использовать обычный цикл for, начинать с конца и уменьшать, вместо того, чтобы начинать сверху и увеличивать.

что-то вроде:

for(int i=foo.lenth; i != 0; i--)
{
do stuff
}
8
ответ дан 3 December 2019 в 13:24
поделиться

Это зависит от того, что вы подразумеваете под list .

  • Список ? Нет, если вы не используете Linq и функцию Reverse ().
  • Ваша индивидуальная коллекция? Легко, просто реализуйте IEnumerator, как вы хотеть.
2
ответ дан 3 December 2019 в 13:24
поделиться

Проверка ошибок опущена для ясности. Используйте собственную реализацию IEnumerable и IEnumerator. Это позволит избежать ненужного копирования.

using System;
using System.Collections.Generic;

namespace ConsoleApplication3
{
    class ReversedEnumerator : IEnumerator<int>
    {
        List<int> v;
        int index;

        public ReversedEnumerator(List<int> v) {
            this.v = v;
            this.index = v.Count;
        }

        public int Current
        {
            get { return v[index]; }
        }

        public void Dispose()
        {
        }

        object System.Collections.IEnumerator.Current
        {
            get { return v[index]; }
        }

        public bool MoveNext()
        {
            return --index >= 0;
        }

        public void Reset()
        {
            index = this.v.Count;
        }
    }

    class EnumeratorStub : IEnumerable<int>
    {
        List<int> v;

        public EnumeratorStub(List<int> v)
        {
            this.v = v;
        }

        public IEnumerator<int> GetEnumerator()
        {
            return new ReversedEnumerator(v);
        }

        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
        {
            return new ReversedEnumerator(v);
        }

    }

    class Program
    {
        static EnumeratorStub Reverse(List<int> v)
        {
            return new EnumeratorStub(v);
        }

        static void Main(string[] args)
        {
            List<int> v = new List<int>();
            v.Add(1);
            v.Add(2);
            v.Add(3);

            foreach (int item in Reverse(v))
            {
                Console.WriteLine(item);
            }

            Console.ReadKey();
        }
    }
}

Я бы рекомендовал рефакторить пример кода, чтобы использовать дженерики. Так вы сможете использовать его для любого типа контейнера.

1
ответ дан 3 December 2019 в 13:24
поделиться

не C #, но вы тоже можете это сделать: -)

    Dim a As New List(Of Integer)
    a.Add(1)
    a.Add(2)
    a.Add(3)

    For Each i In a.AsEnumerable.Reverse
        Debug.Print(i)

    Next
0
ответ дан 3 December 2019 в 13:24
поделиться
IList<String> strList = new IList<String>();
strList.Add("A");
strList.Add("B");
strList.Add("C");

for (int i = strList.Count-1; i>=0;i--)
{
    Console.WriteLine(strList[i]);
}

не пробовал, но должно работать.

0
ответ дан 3 December 2019 в 13:24
поделиться

Вероятно, вы не хотите делать ничего сложного, поэтому я предлагаю просто использовать цикл for.

Однако, если бы это было каким-то образом требованием , вы, безусловно, могли бы реализовать свои собственные итераторы для пользовательского поведения итерации списка.

3
ответ дан 3 December 2019 в 13:24
поделиться
Другие вопросы по тегам:

Похожие вопросы: