2009-11-20 45 views

回答

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); 
    } 
} 
2

使用正常的,當你設置的鍵值對,指定您感興趣的價值的財產。

那是太容易了,我一定是誤解你的要求。

也許你想使用任意屬性,而不是在輸入時。在這種情況下,我認爲你將不得不使用多個字典對象(可能綁定在一個助手類中)。

+1

如果在添加對象後設置對象的屬性,則該對象的屬性將與集合中的鍵不同步。 – Jeremy 2009-11-21 00:37:38

4

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); 
        } 
    } 
    
  • 序列化可能是低效的,因爲它會序列化它的內部列表和它的內部字典。如果需要通過實現自定義序列化,您可以瞭解這一點。

+0

+1,這就是鍵控收集應該如何實施。兩個建議,我會稱之爲'TryGetItem'並使'GetKeys'成爲'Keys'的屬性。 – nawfal 2013-11-01 02:32:38

相關問題