Use Collection<T> and override instead of new and List<T> for HotKeySetCollection

Nov 8, 2012 at 1:28 PM

I think it is better to do it this way instead of the current HotKeySet implementation derived from List<HotKeySet> and using new for methods like Add(HotKeySet x), ...

See the post here which describes the problem:

http://cboard.cprogramming.com/csharp-programming/122536-csharp-lists-can-i-override-add.html

If you use the following any other lib requires only the dependency to ICollection<HotKeySet> (or even IEnumerable<HotKeySet> instead of a complete reference to the real HotKeySetCollection.

    /// <summary>
    /// A collection of HotKeySets
    /// </summary>
    public sealed class HotKeySetCollection : Collection<HotKeySet>
    {
        private delegate void KeyChainHandler(KeyEventArgsExt kex);

        private KeyChainHandler keyChain;

        protected override void InsertItem(int index, HotKeySet item)
        {
            this.keyChain += item.OnKey;
            base.InsertItem(index, item);
        }

        protected override void RemoveItem(int index)
        {
            var item = Items[index];
            this.keyChain -= item.OnKey;
            base.RemoveItem(index);
        }

        protected override void ClearItems()
        {
            foreach (var item in Items)
            {
                this.keyChain -= item.OnKey;   
            }

            base.ClearItems();
        }

        protected override void SetItem(int index, HotKeySet item)
        {
            if (this.Items.Count > index)
            {
                var oldItem = this.Items[index];
                if (oldItem != null) this.keyChain -= oldItem.OnKey;
            }

            this.keyChain += item.OnKey;

            base.SetItem(index, item);
        }

        /// <summary>
        /// Uses a multicase delegate to invoke individual HotKeySets if the Key is in use by any HotKeySets.
        /// </summary>
        /// <param name="e"></param>
        internal void OnKey( KeyEventArgsExt e )
        {
            if (this.keyChain != null)
            {
                this.keyChain(e);
            }
        }
    }

Nov 8, 2012 at 1:35 PM

Onother option which is also more save to use by the client of your lib is to use composition/delegation instead of inheritance:

public sealed class HotKeySetCollection : IList<HotKeySet>
{

    private IList<HotKeySet> list = new List<HotKeySet>;

    .... // implement IList<T> and delegate to list (this way no downcast can pass your implementation as it is possible with the List<HotKeySet> approach) 


}