Сохранение наблюдаемой коллекции


Я использую к ObservableCollection в приложении WPF. Источник данных не обеспечивает изменения. Он предлагает вместо снимков. Метод, который я написал на обновление коллекции ObservableCollection работает, но это выглядит неэлегантно. Есть ли лучший способ сделать это?

    public static void UpdateMarketOrderList(
                          ObservableCollection<MarketOrder> oldList, 
                          List<MarketOrder> newList)
    {
        int oi = 0; // old list iterator
        int ni = 0; // new list iterator

        while (ni < newList.Count)
        {
            if (oi == oldList.Count)
            {
                oldList.Insert(oi, newList[ni]);    
            } 
            else if (oldList[oi].Price == newList[ni].Price)
            {
                if (oldList[oi].Quantity != newList[ni].Quantity)
                {
                    oldList[oi].Quantity = newList[ni].Quantity;
                }
                ++oi;
                ++ni;
            }
            else if (oldList[oi].Price < newList[ni].Price)
            {
                oldList.RemoveAt(oi);
            }
            else if (oldList[oi].Price > newList[ni].Price)
            {
                oldList.Insert(oi, newList[ni]);
            }
        }

        while (oldList.Count > ni)
        {
            oldList.RemoveAt(ni);
        }
    }

Если это важно, то MarketOrder определение можно считать это:

public class MarketOrder 
{
    public decimal Price { get; set; }
    public decimal Quantity { get; set; }
}


7835
4
c#
задан 30 июня 2011 в 06:06 Источник Поделиться
Комментарии
1 ответ

Изучив ваш код немного, вот что я придумал.

Я бы не назвал их итераторы. Они действительно действуя больше как операторы индексирования, который используется как счетчик цикла. Кроме того, они постоянно увеличиваются в синхронизации, и они имеют точно такое же начальное значение.

int oi = 0; // old list iterator
int ni = 0; // new list iterator

Так что я бы заменить просто:

int i = 0;

Второй контур для обрезки лишних элементов:

while (oldList.Count > ni)
{
oldList.RemoveAt(ni);
}

Пост-условие для Я после первой петли должна быть равна newList.Граф в противном случае мы бы до сих пор гоняла первое время. Таким образом, изменение состояния в это яснее:

while (oldList.Count > newList.Count)


После отслеживания вашего UpdateMarketOrderList метода заметный эффект, от того, что я могу сказать, только, кажется, замена oldList с newList. Если это действительно желаемый конечный следствие работает эта функция, почему бы не упростить его, емко этого?

public static void UpdateMarketOrderList( ObservableCollection<MarketOrder> oldList, 
List<MarketOrder> newList )
{
oldList.Clear();

for(int i = 0; i < newList.Count; ++i)
{
oldList.Add(newList[i]);
}
}

Опять же вы не указали в своем вопросе, что пре/пост-условия для UpdateMarketOrderList, что действительно важно.


После прочтения ОП комментарий, что уволили изменить события важны, я бы рефакторинг основной цикл такой:

    while (i < newList.Count)
{
if (i == oldList.Count ||
oldList[i].Price > newList[i].Price)
{
oldList.Insert(i, newList[ni]);
}
else if (oldList[i].Price < newList[i].Price)
{
oldList.RemoveAt(i);
continue;
}
else if (oldList[i].Quantity != newList[i].Quantity)
// && oldList[i].Price == newList[i].Price
{
Debug.Assert(oldList[i].Price == newList[i].Price);
oldList[i].Quantity = newList[i].Quantity;
}

++i;
}

С этого рефакторинга вам уменьшить уровень отступа и затяните петлю немного при сохранении существующего поведения. Главное понимать, что RemoveAt не инкремент счетчика цикла. Ваш предыдущий код сделал это в немного менее прямым образом.

У меня такое чувство, что это может быть переработан еще дальше, но без хорошей идеи из ожидаемых побочных эффектов и иным требованиям для данного метода, его будет сложно выполнить рефакторинг этого.

3
ответ дан 1 июля 2011 в 10:07 Источник Поделиться