不是使用Dictionary<TKey,TValue>
我想要某种类型的集合类可以使用值的属性作为键,是否有这样的东西?
答案 0 :(得分:9)
是的,有 - 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);
}
}
答案 1 :(得分:4)
Jon Skeet所说的KeyedCollection是明显的候选人。
关于这个课程的一些随机评论:
您当然希望您用作密钥的财产是只读的。
它的方法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);
}
}
序列化可能效率低下,因为它会序列化其内部列表和内部字典。如果需要,可以通过实现自定义序列化来解决这个问题。
答案 2 :(得分:2)
使用普通值,并在设置键值对时,指定您感兴趣的值的属性。
这太容易了,我一定是误解了你的要求。
也许你想在以后而不是在输入时使用任意属性。在这种情况下,我认为你将不得不使用多个字典对象(可能在一个辅助类中绑定在一起)。