【问题标题】:Is there a dictionary like collection that can use a property of its value as the key?是否有像集合这样的字典可以使用其值的属性作为键?
【发布时间】:2010-12-18 22:32:33
【问题描述】:

我想要某种类型的集合类,而不是使用Dictionary<TKey,TValue>,它可以使用值的属性作为键,有这样的东西吗?

【问题讨论】:

    标签: .net collections dictionary


    【解决方案1】:

    是的,有 - System.Collections.ObjectModel.KeyedCollection<TKey, TValue>

    这是抽象的,据我所知,框架中没有具体的派生类,但据我所知,您需要实现的只是GetKeyForItem。例如,您可以使用委托来执行此操作:

    public class DelegatingKeyedCollection<TKey, TItem> : System.Collections.ObjectModel.KeyedCollection<TKey, TItem>
    {
        private readonly Func<TItem, TKey> keySelector;
    
        public DelegatingKeyedCollection(Func<TItem, TKey> keySelector)
        {
            this.keySelector = keySelector;
        }
    
        protected override TKey GetKeyForItem(TItem item)
        {
            return keySelector(item);
        }
    }
    

    【讨论】:

      【解决方案2】:

      正如 Jon Skeet 所说,KeyedCollection 是显而易见的候选者。

      关于这个类的一些随机评论:

      • 您当然希望用作键的属性是只读的。

      • 它的方法Contains(TItem item)继承自Collection&lt;T&gt;,通过遍历集合来实现。因此,这可能比Contains(TKey key) 慢得多。开发人员很容易犯错误使用错误的重载,因此可能值得考虑实现自己的Contains(TItem item) 方法:

        public new bool Contains(TItem item)
        {
            if (item == null) throw new ArgumentNullException("item");
            return this.Contains(GetKeyForItem(item));
        }
        
      • 与 IDictionary 不同,它没有方法 TryGetValue。这可能很有用,可能值得您自己实现:

        public bool TryGetValue(TKey key, out TItem item)
        {
            // If the dictionary exists, use it
            if (Dictionary != null) return Dictionary.TryGetValue(key, out item);
            // Else do it the hard way
            if (!this.Contains(key))
            {
                item = default(TItem);
                return false;
            }
            item = this[key];
            return true;
        }
        
      • 它不支持键的枚举,这很有用:

        public IEnumerable<TKey> GetKeys()
        {
            foreach (TItem item in this)
            {
                yield return GetKeyForItem(item);
            }
        }
        
      • 序列化可能效率低下,因为它会同时序列化其内部列表和内部字典。如果需要,您可以通过实现自定义序列化来解决这个问题。

      【讨论】:

      • +1,这就是 keyed collection 应该如何实现的。有两个建议,我将其命名为 TryGetItem 并将 GetKeys 设为类似于 Keys 的属性。
      【解决方案3】:

      使用普通的,设置键值对的时候,指定你感兴趣的值的属性。

      这太简单了,我一定是误解了你的要求。

      也许您想稍后而不是在输入时使用任意属性。在这种情况下,我认为您将不得不使用多个字典对象(可能在一个辅助类中捆绑在一起)。

      【讨论】:

      • 如果在添加后设置对象的属性,会与集合中的key不同步。
      猜你喜欢
      • 1970-01-01
      • 2022-01-25
      • 1970-01-01
      • 2013-01-09
      • 2019-03-26
      • 2011-01-01
      • 2011-04-03
      • 2010-09-25
      相关资源
      最近更新 更多