public class Program { private static void Main(string[] args) { var keyd2 = new KeyedCollectionEx<string, MyData>(myData => myData.Name); var md = new MyData { Name = "Tom", Data = "Test" }; keyd2.Upsert(md); md.Data = "Changed"; keyd2.Upsert(md); var md2 = new MyData {Name = "Dick", Data = "New"}; keyd2.Upsert(md2); } } public class MyData { public string Name{ get; set; } public string Data { get; set; } } public class KeyedCollectionEx<TKey, TItem> : KeyedCollection<TKey, TItem> { private readonly Func<TItem, TKey> _getKeyForItemDelegate; public KeyedCollectionEx(Func<TItem, TKey> getKeyForItemDelegate) : base() { if (getKeyForItemDelegate == null) throw new ArgumentNullException(); _getKeyForItemDelegate = getKeyForItemDelegate; } protected override TKey GetKeyForItem(TItem item) { return _getKeyForItemDelegate(item); } public void Upsert(TItem input) { int i = IndexOf(input); if (i == -1){Add(input);} else{SetItem(i,input);} } }