解决ObservableDictionary继承Dictionary时构造器调用编译报错问题
问题解决与代码优化
编译报错原因
Dictionary<TKey, TValue>的构造器没有接受IEqualityComparer<TValue>的重载,它的 comparer 参数是用于比较**字典的键(TKey)**的,类型为IEqualityComparer<TKey>。你传入的是针对TValue的比较器,类型不匹配,因此编译报错。
修正方案与功能完善
根据你“仅在对象发生变化时触发事件”的需求,我们需要:
- 调整构造器逻辑,区分键比较器(传给基类)和值比较器(用于自身判断值变化)
- 添加值变化时的事件触发逻辑
以下是修正后的完整代码:
using System.Collections.Generic; using System.ComponentModel; public class ObservableDictionary<TKey, TValue> : Dictionary<TKey, TValue>, INotifyPropertyChanged { // 用于值比较的自定义比较器,默认使用系统默认实现 private readonly IEqualityComparer<TValue> _valueComparer; // 值变化触发的事件 public event PropertyChangedEventHandler PropertyChanged; // 默认构造 public ObservableDictionary() : this(null) { } // 同时接受键比较器和值比较器的构造 public ObservableDictionary(IEqualityComparer<TKey> keyComparer, IEqualityComparer<TValue> valueComparer = null) : base(keyComparer) { _valueComparer = valueComparer ?? EqualityComparer<TValue>.Default; } // 仅接受值比较器的构造(键使用默认比较逻辑) public ObservableDictionary(IEqualityComparer<TValue> valueComparer) : this(null, valueComparer) { } public new TValue this[TKey key] { get => base[key]; set { bool isNewKey = !ContainsKey(key); if (isNewKey) { base.Add(key, value); OnPropertyChanged($"Item[{key}]"); OnPropertyChanged("Count"); } else { var oldValue = base[key]; // 使用自定义比较器判断值是否真的变化 if (!_valueComparer.Equals(oldValue, value)) { base[key] = value; OnPropertyChanged($"Item[{key}]"); } } } } // 事件触发辅助方法 protected virtual void OnPropertyChanged(string propertyName) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } } class CarDiffRank : EqualityComparer<Car> { public override bool Equals(Car c1, Car c2) { return c1?.rank == c2?.rank; // 增加空引用防护 } public override int GetHashCode(Car c) { return c?.rank.GetHashCode() ?? 0; // 处理null场景 } } // 示例Car类 class Car { public int rank { get; set; } }
关键说明
- 构造器拆分:明确区分了给基类用的键比较器和自身用于值判断的比较器,提供多种重载适配不同使用场景
- 精准触发事件:仅在新增键、或者值通过自定义比较器判定为真的变化时,才触发
PropertyChanged事件 - 空引用防护:在
CarDiffRank的方法中增加了null判断,避免运行时异常
内容的提问来源于stack exchange,提问作者rba
相关产品推荐
相关产品推荐

