Реагирование на изменения в SortedDictionary - PullRequest
1 голос
/ 01 сентября 2009

Я создал новый класс, который наследуется от SortedDictionary:

public partial class ListIncomeWeight : SortedDictionary<string, double> { 
    public Guid Identity { get; set; }
}

Этот список объединен с несколькими десятками других списков, где другие списки будут отслеживать, рассчитаны ли они уже с этим списком или нет. Для этого они используют словарь для сохранения результата, если он был рассчитан ранее.

Логика, стоящая за Идентичностью, заключается в том, что он будет уникально идентифицировать список, когда он используется в каком-то другом вычислении. Таким образом, когда я повторяю вычисление, я сначала проверяю GUID, чтобы увидеть, вычислял ли я его раньше. Если так, я уже знаю результат этого вычисления и могу сэкономить некоторое время, не повторяя этот список снова. (Расчеты сложны, и мне нужно сделать много из них, поэтому, хотя это небольшое сокращение на расчёт, это экономит время).

Однако, что происходит, когда я создаю список, добавляю некоторые элементы, вычисляю, добавляю еще несколько элементов и вычисляю снова? В этом случае я не получу ожидаемый результат, потому что в расчете никогда не использовались новые элементы. Поэтому мне нужно обойти это.

Моя идея проста: изменять GUID при каждом добавлении или удалении элемента. Конечно, я мог бы переопределить методы Add / Remove, но я хочу что-то более общее. Есть ли какой-нибудь делегат или событие, которое я могу использовать, чтобы ответить на изменения в этом списке?


Некоторые дальнейшие объяснения ... У меня есть два набора списков. Один набор списков содержит обзор того, сколько кто-то зарабатывает. (Заработная плата, резерв, проценты, проценты со сберегательных счетов и т. Д.) Второй набор списков определяет весовой коэффициент для каждого типа дохода. Это набор правил, который говорит мне, что зарплата считается 100%, но предоставляется только для 75% и т. Д. Эти списки веса добавят все после применения весового коэффициента, в результате чего будет получена окончательная сумма.

Мне приходится иметь дело с доходом от человека и его партнера, плюс доход до и после выхода на пенсию. Плюс доход, который не зависит от выхода на пенсию. Таким образом, у меня есть около 6 списков доходов на человека.

У меня также есть несколько десятков списков веса. Их используют около 1600 различных продуктов, и в худшем случае мне нужно сделать полмиллиона расчетов. Мне нужно уменьшить это число, поэтому мне нужно много оптимизаций. Это только часть этих оптимизаций.

В общем, мне нужно объединить списки доходов со списками весов, что дает пару значений. Один из них используется для поиска, другой - для подсчета того, сколько человек может тратить в год на затраты на продукт, а еще один является поправкой к этой сумме. И есть еще несколько комбинаций доход / вес, которые мне нужно принять в уравнение, но в целом это зависит от самого расчета. В расчете также используется процентная ставка, которая довольно сильно варьируется, хотя, как правило, находится на небольшом расстоянии. Я уже оптимизировал эту часть, просто рассчитав различные процентные ставки. Но теперь я хочу уменьшить количество расчетов, необходимых для расчета этих взвешенных доходов. Если мне повезет, я смогу сократить количество вычислений с полумиллиона до нескольких тысяч, а возможно, и меньше.

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

Ответы [ 2 ]

1 голос
/ 01 сентября 2009

Я думаю, что вам даже нужно немного переписать свой класс ListIncomeWeight, обновляя Guid при изменении списка (Add, Remove, Clear). Я установил флаг, который говорит, что внутренний список изменился или нет. Свойство Identity обновляется на основе этого флага. Почему бы не создать событие для этого: Changed

public partial class ListIncomeWeight : SortedDictionary<string, double>
{
    public delegate void ChangedHandler();
    public event ChangedHandler Changed;

    private Guid _guid;
    private bool _changed = false;

    private void RaiseChanged()
    {
        _changed = true;
        if (Changed != null) Changed();
    }

    public new void Add(string key, double value)
    {
        base.Add(key, value);
        RaiseChanged();
    }

    public new void Clear()
    {
        base.Clear();
        RaiseChanged();
    }

    public new bool Remove(string key)
    {            
        bool res = base.Remove(key);

        RaiseChanged();

        return res;
    }

    public Guid Identity
    {
        get
        {
            if (_changed)
            {
                _guid = new Guid();
                _changed = false;
            }
            return _guid;
        }
        set {
            _guid = value;
        }
    }        
}
1 голос
/ 01 сентября 2009

Я не думаю, что существует какой-либо общий способ получения обратных вызовов при изменении.

С другой стороны, я заблудился из-за вашей логики - вы используете GUID для определения уникального вычисления, но затем вы как бы меняете это вычисление (меняете словарь с результатами)? Не будет ли проще создать копию словаря с новым GUID при добавлении новых элементов? (извините, я не очень понимаю, как это работает)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...