I find myself often faced with this problem: I have a dictionary where the key is some simple numeric ID and the value is an object. The ID is also contained in a specific property of that value object.
Then, I want to be able to deserialize some (format-inflexible) XML that looks like:
<listitem>
<id>20359</id>
<someotherval>foo</someotherval>
</listitem>
<listitem>
...
This requires me to deserialize with a List<V>
, and it's inconvenient to have to manually convert that to a Dictionary<K,V>
.
The second issue is with binding. Binding lists require that the source implements ICollection
(if I remember correctly), and again it's a pain to have to manually create a new List<V>
and populate it from the Dictionary<K,V>
.
My current, fairly ugly but functional solution is to have the following classes:
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>();
// ...
}
This works, but it's internally large and ugly. Are there any better ways?
EDIT: Here is the solution I've settled on.
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; }
}