EventList a generic list implementation that raises events when items are added and removed I created this class for a project when I wanted to have List&lt;T&gt; properties on a class and also listen for items being added and removed. 

I looked at using BindingList&lt;T&gt; or ObservableCollection&lt;T&gt; but I felt that their collection changed events are too complicated. I simply wanted to know when items are added and removed.

public class EventList&lt;T&gt; : IList&lt;T&gt;
{
    private readonly List&lt;T&gt; _list;

    public EventList()
    {
        _list = new List&lt;T&gt;();
    }

    public EventList(IEnumerable&lt;T&gt; collection)
    {
        _list = new List&lt;T&gt;(collection);
    }

    public EventList(int capacity)
    {
        _list = new List&lt;T&gt;(capacity);
    }

    public event EventHandler&lt;EventListArgs&lt;T&gt;&gt; ItemAdded;
    public event EventHandler&lt;EventListArgs&lt;T&gt;&gt; ItemRemoved;

    private void RaiseEvent(EventHandler&lt;EventListArgs&lt;T&gt;&gt; eventHandler, T item, int index)
    {
        var eh = eventHandler;
        eh?.Invoke(this, new EventListArgs&lt;T&gt;(item, index));
    }

    public IEnumerator&lt;T&gt; GetEnumerator()
    {
        return _list.GetEnumerator();
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }

    public void Add(T item)
    {
        var index = _list.Count;
        _list.Add(item);
        RaiseEvent(ItemAdded, item, index);
    }

    public void Clear()
    {
        for (var index = 0; index &lt; _list.Count; index++)
        {
            var item = _list[index];
            RaiseEvent(ItemRemoved, item, index);
        }

        _list.Clear();
    }

    public bool Contains(T item)
    {
        return _list.Contains(item);
    }

    public void CopyTo(T[] array, int arrayIndex)
    {
        _list.CopyTo(array, arrayIndex);
    }

    public bool Remove(T item)
    {
        var index = _list.IndexOf(item);

        if (_list.Remove(item))
        {
            RaiseEvent(ItemRemoved, item, index);
            return true;
        }

        return false;
    }

    public int Count =&gt; _list.Count;
    public bool IsReadOnly =&gt; false;

    public int IndexOf(T item)
    {
        return _list.IndexOf(item);
    }

    public void Insert(int index, T item)
    {
        _list.Insert(index, item);
        RaiseEvent(ItemRemoved, item, index);
    }

    public void RemoveAt(int index)
    {
        var item = _list[index];
        _list.RemoveAt(index);
        RaiseEvent(ItemRemoved, item, index);
    }

    public T this[int index]
    {
        get { return _list[index]; }
        set { _list[index] = value; }
    }
}

public class EventListArgs&lt;T&gt; : EventArgs
{
    public EventListArgs(T item, int index)
    {
        Item = item;
        Index = index;
    }

    public T Item { get; }
    public int Index { get; }
}


The typical use case would be something like this:

public class MyClass
{
    public MyClass()
    {
        MyItems = new EventList&lt;string&gt;();

        MyItems.ItemAdded += (sender, args) =&gt;
        {
            // do something when items are added
        };

        MyItems.ItemRemoved += (sender, args) =&gt;
        {
            // do something when items are removed
        };
    }

    public EventList&lt;string&gt; MyItems { get; } 
}


I'm posting this here for code review for general feedback, but also to ask if I've missed something obvious, like an alternative class in the .NET framework or a 3rd party library that might do the same sort of thing?
Bug  


public void Insert(int index, T item)
{
    _list.Insert(index, item);
    RaiseEvent(ItemRemoved, item, index);
}  



I don't think that you want to raise an ItemRemoved event in the case of inserting an item.  



In general I like your implementation. It is leightweight and is doing exactly what it should.  

But for sure I have something to critizise:  


The name EventList&lt;T&gt; which reads like a list of events instead of a list with events. Because there is already a ObservableCollection&lt;T&gt; maybe an ObservableList&lt;T&gt; would be a better name.  
You implement IList&lt;T&gt; but have the underlaying list as a List&lt;T&gt; instead of an IList&lt;T&gt; like private readonly IList&lt;T&gt; _list;.  
The RemoveAt() could be simplified by calling the Remove() method like so  

public void RemoveAt(int index)
{
    Remove(_list[index]);
}  


 See @RomanReiner's answer here
IMO the raising of multiple ItemRemoved events inside the Clear() method isn't that good because you are raising the event before the item is removed. You should either have an additional event ItemsCleared or you should raise the ItemRemoved events after the clearing of that list.