是否有像集合这样的字典可以使用它的值的属性作为关键?
是的,有 - 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);
}
}
使用正常的,当你设置的键值对,指定您感兴趣的价值的财产。
那是太容易了,我一定是误解你的要求。
也许你想使用任意属性,而不是在输入时。在这种情况下,我认为你将不得不使用多个字典对象(可能绑定在一个助手类中)。
KeyedCollection作为Jon Skeet说是明显的候选人。
一些关于这个类随机备注:
你当然会希望您使用的关键是只读属性。
-
其方法
Contains(TItem item)
从Collection<T>
继承,并通过迭代通过集合实现。因此这可能比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,这就是键控收集应该如何实施。两个建议,我会称之为'TryGetItem'并使'GetKeys'成为'Keys'的属性。 – nawfal 2013-11-01 02:32:38
如果在添加对象后设置对象的属性,则该对象的属性将与集合中的键不同步。 – Jeremy 2009-11-21 00:37:38