【问题标题】:Responding to changes in a SortedDictionary响应 SortedDictionary 中的更改
【发布时间】:2009-09-01 09:55:04
【问题描述】:

我创建了一个继承自 SortedDictionary 的新类:

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

此列表与几十个其他列表组合在一起,如果其他列表已经使用此列表进行计算,则其他列表将跟踪它们。为此,他们使用字典来存储之前计算过的结果。

Identity 背后的逻辑是,当它用于其他一些计算时,它将唯一标识列表。这样,当我重复计算时,我首先检查 GUID 以查看我之前是否计算过它。如果是这样,我已经知道这个计算的结果,并且可以通过不必再次遍历这个列表来节省一些时间。 (计算很复杂,我需要做很多,所以即使每次计算减少了一点,但它确实可以节省时间。)

但是,当我创建列表、添加一些项目、计算、添加更多项目并再次计算时会发生什么?在这种情况下,我不会得到预期的结果,因为计算从未使用过新项目。所以我需要解决这个问题。

我的想法很简单:在添加或删除项目时更改 GUID。当然,我可以覆盖 Add/Remove 方法,但我想要更通用的东西。是否有一些委托或事件可用于响应此列表中的更改?


一些进一步的解释... 我有两组列表。一组列表包含有关某人收入的概述。 (工资、准备金、利息、储蓄账户的利息等)第二组列表定义了每种收入类型的权重因子。这是一个规则集,它告诉我工资计为 100%,但仅提供 75% 等。这些权重列表将在应用权重因子后添加所有内容,从而得出最终金额。

我必须处理一个人及其伴侣的收入,以及退休前后的收入。加上不依赖于退休的收入。因此,我有大约 6 个人均收入清单。

我还有几十个重量清单。这些被大约 1600 种不同的产品使用,最坏的情况是我必须进行 50 万次计算。我需要减少这个数字,因此我需要很多优化。这只是这些优化的一部分。

一般来说,我需要将收入列表与权重列表结合起来,从而产生几个值。其中一个用于查找,另一个用于计算一个人每年可以在产品成本上花费多少,还有一个是对该金额的修正。还有一些我需要考虑的收入/体重组合,但总的来说这取决于计算本身。该计算还使用了利率,尽管利率往往在短期内,但变化很大。我已经通过计算不同的利率来优化这部分。但现在我想减少计算这些加权收入所需的计算次数。如果运气好的话,我应该能够将计算次数从 50 万减少到几千,甚至可能更少。

这就是为什么我想知道此权重列表中的值是否已添加或删除。发生这种情况时,它会变成不同的列表,因此需要不同的 GUID。我正在开发一个通用类库,并且对如何使用它没有太多控制权,所以我需要确保其他开发人员不能以某种错误的方式使用它。这就是为什么这个功能会非常有用。

【问题讨论】:

    标签: c# dictionary delegates


    【解决方案1】:

    我认为您必须通过在列表更改(添加、删除、清除)时更新 Guid 来重写您的 ListIncomeWeight 类。我设置了一个标志,告诉内部列表是否更改。身份属性根据此标志更新。为什么不为此创建一个事件: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;
            }
        }        
    }
    

    【讨论】:

      【解决方案2】:

      我认为没有任何通用的方法可以在更改时获得回调。

      另一方面,我迷失了你的逻辑 - 你使用 GUID 来识别唯一的计算,但是你改变了这个计算(用结果更改字典)?添加新项目时使用新的 GUID 创建字典的副本不是更容易吗? (抱歉,我不太明白它是如何工作的)

      【讨论】:

      • 在 Q 中添加了更多文本。但基本上,我有两组列表,我需要将集合 A 中的任何列表与集合 B 中的任何列表结合起来,并在列表 B 中记住这个结果。
      • 可以在我添加值时添加列表的副本。不幸的是,这些值总是一个一个地添加,因此我最终可能会得到一大堆类似的副本。 (是的,复杂的是列表中的列表...)
      猜你喜欢
      • 1970-01-01
      • 2014-03-31
      • 2012-10-16
      • 1970-01-01
      • 2016-06-18
      • 1970-01-01
      • 1970-01-01
      • 2016-05-30
      • 1970-01-01
      相关资源
      最近更新 更多