Как избежать изменения порядка товаров в контейнере после использования метода расширения «Выбрать»? - PullRequest
0 голосов
/ 05 февраля 2011

Вот фрагмент кода:

public class Schema
{
    public Schema(List<CountryParticipantsStages> places)
    {
        Places = places.Select(participant =>(AbstractGeneralParticipants) new GeneralParticipants(participant)).ToList();
    }
...

Порядок элементов в исходном и результирующем списках будет одинаковым, если исходный список повторяется полностью.Но если в середине любой итерации вызывается конструктор «Схема», порядок элементов в списке «Места» будет смещен ...

Чтобы избежать этого, я вижу единственный способ использовать неЦикл «method for a», который будет идти от 0-го элемента:

public class Schema
{
    public Schema(List<CountryParticipantsStages> places)
    {
        Places = new List<AbstractGeneralParticipants>(places.Count);
        for (int i = 0; i < places.Count; i++)
        {
            Places.Add(new GeneralParticipants(places[i]));
        }
    }

Вторая функция выглядит неприятно, но лучшего способа для этого я не вижу.А также, ReSharper предлагает мне повторить цикл for с foreach ...

Пожалуйста, сообщите.

Большое спасибо.

Ответы [ 3 ]

1 голос
/ 05 февраля 2011

Вы ошибаетесь, считая, что если список повторяется в каком-то месте программы, его текущая позиция смещается при передаче в качестве параметра.

В списке нет текущего индекса или состояния. Это код клиента, который делает.

То, что делает foreach, по сути, вызывает метод GetEnumerator и использует IEnumerator для продвижения вперед и чтения текущего значения. Как только вы передадите список в другое место, другой foreach получит свой собственный IEnumerator, который снова начинается с первого элемента.

Рассмотрим этот образец:

void InnerEnumerate (List<int> innerList)
{
    foreach (var innerItem in innerList)
        Console.WriteLine ("- inner item {0}", innerItem);
}

var outerList = new List<int> { 1, 2, 3 };
foreach (var outerItem in outerList) {
    Console.WriteLine ("Outer item {0}", outerItem);
    InnerEnumerate (outerList); // pass list as a parameter
}

Это вывод:

Outer item 1
- inner item 1
- inner item 2
- inner item 3
Outer item 2
- inner item 1
- inner item 2
- inner item 3
Outer item 3
- inner item 1
- inner item 2
- inner item 3

Как видите, foreach независимы и ничего не знают друг о друге. Они всегда начинаются с самого начала.

0 голосов
/ 05 февраля 2011

Угадайте, лучшим решением будет избегать полагаться на порядок пунктов в списке. Вместо этого было бы лучше добавить дополнительный параметр в класс CountryParticipantsStages, который будет использоваться для определения его «позиции» в списке.

0 голосов
/ 05 февраля 2011

Во втором примере вы можете использовать цикл foreach, как предложил Resharper:

Places = new List<AbstractGeneralParticipants>(places.Count);
foreach (Place place in places)
{
    Places.Add(new GeneralParticipants(place));
}

Или вы также можете сделать это, используя LINQ, как в первом примере, который немного более лаконичен.

...