【问题标题】:How can I make an Observable Hashset in C#?如何在 C# 中创建 Observable Hashset?
【发布时间】:2009-02-09 02:28:07
【问题描述】:

目前我在 WPF 应用程序中使用 ObservableCollection,该应用程序是 Conway 的生命游戏的实现,适用于大约 500 个单元格,但之后它开始显着减慢。我最初使用 HashSet 编写应用程序,但找不到将单元格绑定到画布的任何方法。

有没有办法让我的 HashSet 通知其绑定对象的更改?我的 Cell 类是一个简单的整数 X,Y 对,如果该对存在,则单元格是活的,否则是死的。 Cell 实现 INotifyPropertyChanged 并覆盖 GetHashCode 和 Equals。我无法让单元格显示任何更改,只有加载后立即出现的单元格。有什么方法可以将 Hashset 绑定到 Canvas 上的项目?

【问题讨论】:

    标签: c# wpf data-binding


    【解决方案1】:

    我不知道这是否会有所帮助,但这是我为个人项目制作的“可观察集”的真正简单实现。它本质上防止插入(或覆盖)集合中已经存在的项目。

    如果你愿意,你可以简单地从方法中返回而不是抛出异常。

    public class SetCollection<T> : ObservableCollection<T> 
    {
        protected override void InsertItem(int index, T item)
        {
            if (Contains(item)) throw new ItemExistsException(item);
    
            base.InsertItem(index, item);
        }
    
        protected override void SetItem(int index, T item)
        {
            int i = IndexOf(item);
            if (i >= 0 && i != index) throw new ItemExistsException(item);
    
            base.SetItem(index, item);
        }
    }
    

    【讨论】:

    • 这与我已经拥有的非常接近,我使用 observablecollection 并简单地保证所有项目都是唯一的。在我的代码中,而不是通过继承,但嘿,我是个懦夫;)
    • 是的,我想说这比重新实现 HashSet 以实现 INotifyCollectionChanged 更容易。 ObservableCollection 已经为您完成了所有艰苦的工作。
    • 离开反射器,您似乎只想公开默认构造函数或自己实现其他构造函数,因为基础调用私有 CopyFrom 方法而不是 InsertItem
    • -1 因为这不是真正的集合,因为它(在代码隐藏中)使用索引。设置增益性能,因为它们是基于对象引用的。在此实现中,不会获得相同的性能增益。实际上,性能会差很多。
    • 一个集合定义了行为,而不是实现。这是一个集合,但是一个用于插入、更新、查找的 O(n)。
    【解决方案2】:

    您也必须实现INotifyCollectionChanged,然后它应该一切正常。还有另一个相关的 SO 答案,uses freezables 以确保基础实体的更改也得到处理。

    【讨论】:

    • 嗯,我去看看,INotifyCollectionChanged 可能只是我缺少的链接,谢谢!
    【解决方案3】:

    我在这里发布了一个完整的 ObservableHashSet 供您使用。

    https://github.com/BellaCode/Public/tree/master/ObservableHashSet

    它基于对 ObservableCollection 实现方式的反思,并提供相同的线程安全重入检查。

    【讨论】:

    • 很好,但是要填充newItemsoldItems 集合,您需要执行一些非常慢的操作。我可能会添加一个选项,根本不填写这些内容,只报告通过引发事件发生的变化。
    • int index = this.hashSet.IndexOf(item); 错误Error 1 'System.Collections.Generic.HashSet&lt;T&gt;' does not contain a definition for 'IndexOf' and no extension method 'IndexOf' accepting a first argument of type 'System.Collections.Generic.HashSet&lt;T&gt;' could be found (are you missing a using directive or an assembly reference?)
    • 过多的无关依赖;过度设计。请参阅下面的更简单的解决方案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-06
    • 1970-01-01
    • 2013-09-30
    • 1970-01-01
    • 2019-11-17
    • 1970-01-01
    相关资源
    最近更新 更多