2010-07-23 101 views
1

我發現自己經常面臨這個問題:我有一個字典,其中的關鍵是一些簡單的數字ID和值是一個對象。該ID也包含在該值對象的特定屬性中。字典<K,V>實現IList <V>

然後,我希望能夠反序列化一些(格式不靈活),XML,看起來像:

<listitem> 
    <id>20359</id> 
    <someotherval>foo</someotherval> 
</listitem> 
<listitem> 
    ... 

這需要我用List<V>反序列化,這是不方便,要手動將其轉換成一個Dictionary<K,V>

第二個問題是綁定。綁定列表要求源實現ICollection(如果我沒有記錯的話),並且再次手動創建新的List<V>並從Dictionary<K,V>填充它是一件很痛苦的事情。

我現在,相當難看但實用的解決方案是有以下類:

public abstract class Keyed<KeyType> 
{ 
public KeyType key { get; set; } 
} 

public class KeyedDictionary<KeyType, ValueType> : 
Dictionary<KeyType, ValueType> 
where ValueType : Keyed<KeyType> 
{ 
// ... 
} 

public class KeyedList<KeyType, ValueType> : 
IList<ValueType>, 
System.Collections.IList 
where ValueType : Keyed<KeyType> 
{ 
public readonly KeyedDictionary<KeyType, ValueType> dict = 
    new KeyedDictionary<KeyType, ValueType>(); 

// ... 
} 

這工作,但它的內部大和醜陋。有沒有更好的方法?


編輯:這是我解決的解決方案。

public interface IKeyed<KeyType> 
{ 
    KeyType Key { get; } 
} 

public class KeyedList<KeyType, ValueType> : 
    KeyedCollection<KeyType, ValueType> 
    where ValueType : IKeyed<KeyType> 
{ 
    protected override KeyType GetKeyForItem(ValueType item) { return item.Key; } 
} 
+0

這對我來說確實很不錯。它符合要求,它是直接的泛型和接口,沒有tomfoolery。 – 2010-07-24 00:00:36

+0

除非你的問題是關於C#編程語言,否則請保留「C#」。這個問題是關於.NET,而不是關於C#。 C#就是您正在編寫的語言,以便您可以使用.NET。 – 2010-07-24 01:37:33

回答

3

這聽起來像內置的KeyedCollection<K,I>類型可能會伎倆。這是一個抽象類,因此您需要派生自己的具體子類,但這很容易。

您可以根據您的確切需求創建單獨的專用實現,也可以創建一個接受鍵選擇器委託作爲構造函數參數的單個通用版本。 (在通用版本將略高於專門的版本不太有效,因爲每個有一個鍵查找時間委託調用的成本。)

var myKeyedByIdCollection = 
    new ProjectionKeyedCollection<int, MyCustomType>(i => i.Id); 

// ... 

public class ProjectionKeyedCollection<TKey, TItem> 
    : KeyedCollection<TKey, TItem> 
{ 
    private readonly Func<TItem, TKey> _keySelector; 

    public ProjectionKeyedCollection(Func<TItem, TKey> keySelector) 
    { 
     if (keySelector == null) 
      throw new ArgumentNullException("keySelector"); 

     _keySelector = keySelector; 
    } 

    protected override TKey GetKeyForItem(TItem item) 
    { 
     return _keySelector(item); 
    } 
} 
+1

好的答案,除了一件事:這個泛型集合可以序列化爲XML,但不是反序列化的,因爲它沒有無參數的構造函數。有兩種方法可以解決這個問題:1.將集合包裝在初始化它的類中; 2.派生一個提供無參數構造函數的類的專門版本 – 2010-07-24 00:46:00

+0

謝謝!我希望我在一年前知道KeyedCollection!我將在問題中粘貼我的實現。 – Reinderien 2010-07-24 14:12:40

0

什麼只是反序列化到List<something>,然後用.ToDictionary()那個清單?這看起來不太方便。

+0

這是不理想的,因爲然後在字典上的任何操作後,我不得不做相反的.ToList()爲了做綁定或序列化。理想情況下,不必保持字典和列表同步,它們將是同一個對象。 – Reinderien 2010-07-24 02:15:21

相關問題