As a result I wanted a collection where it's possible to grab an item quickly and easily using either of the identifiers. Deriving from KeyedCollection<TKey, TItem> does the job nicely for a single key, so I thought I'd extend that a bit farther and come up with my own cunningly named DoubleKeyedCollection<TKey, TSecondKey, TItem>.
To my shame, I've not even tested this code before posting it up here as it's already long past the end of the day, although it does compile, which is always encouraging if nothing else. I'm not hugely fond of the choice of GetItem() as a method name as it's a bit ambiguous, especially if your two keys are of the same type. GetItemBySecondKey() seemed a bit meaningless to an end client using a class derived from DoubleKeyedCollection though. Any thoughts on the subject are welcome (as is notification of any blatant errors that I've managed to completely overlook).
As an aside, I think I'll be examining the possibilities of changing the layout of this page. The narrow column doesn't exactly lend itself to code listings. I've done what I can to make it readable. EDIT: Template now changed - not as pretty imho, but makes the code a lot easier to read!
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
namespace Diuturnal.Utility { | |
[Serializable] | |
public abstract class DoubleKeyedCollection<TKey, TSecondKey, TItem> | |
: KeyedCollection<TKey, TItem> { | |
private Dictionary<TSecondKey, TKey> _secondKeyIndex = | |
new Dictionary<TSecondKey, TKey>(); | |
public TItem GetItem(TSecondKey secondKey) { | |
return this[_secondKeyIndex[secondKey]]; | |
} | |
protected abstract TSecondKey GetSecondKeyForItem(TItem item); | |
protected override void InsertItem(int index, TItem item) { | |
base.InsertItem(index, item); | |
AddSecondKeyIndex(this.GetSecondKeyForItem(item), | |
this.GetKeyForItem(item)); | |
} | |
protected override void RemoveItem(int index) { | |
RemoveSecondKeyIndex(this.GetSecondKeyForItem(this[index])); | |
base.RemoveItem(index); | |
} | |
protected override void SetItem(int index, TItem item) { | |
RemoveSecondKeyIndex(this.GetSecondKeyForItem(this[index])); | |
base.SetItem(index, item); | |
AddSecondKeyIndex(this.GetSecondKeyForItem(item), | |
this.GetKeyForItem(item)); | |
} | |
protected override void ClearItems() { | |
base.ClearItems(); | |
_secondKeyIndex.Clear(); | |
} | |
private void AddSecondKeyIndex(TSecondKey secondKey, TKey key) { | |
_secondKeyIndex.Add(secondKey, key); | |
} | |
private void RemoveSecondKeyIndex(TSecondKey secondKey) { | |
_secondKeyIndex.Remove(secondKey); | |
} | |
} | |
} |
No comments:
Post a Comment