Posts Tagged ‘List’

WCF; Client proxy turns lists into arrays

June 15, 2010

If you find that lists from your DataContract classes are being converted into arrays in the proxy class, then you need to configure the client’s service reference and set collection type.

image

image

Lists that notify when items are added & removed

April 11, 2010

I often find myself wishing that collections such as List<T> could issue notifications when changes are made to the collection.

This could be particularly useful when you expose a collection as a property from a class. It is often desirable to perform some action on the class if the client changes the collection.

Averager averager = new Averager();
IList<double> numbers = averager.Numbers;

numbers.Add(10);
numbers.Add(5);

Assert.IsTrue(averager.Average == 7.5);

numbers.Add(32);

Assert.IsTrue(averager.Average == 15.666666666666666);

In the code above you can see that Averager passes out a standard list. We can modify the list externally and yet the averager object is kept up to date.

public class Averager {
    public Averager() {
        numbers = new ListNotifyChanged<double>();
        numbers.Changed += numbers_Changed;
    }

    public double Average { get; private set; }

    ListNotifyChanged<double> numbers = null;
    public IList<double> Numbers { get { return numbers; } }

    void numbers_Changed( object sender, ListNotifyChanged<double>.ChangedEventArgs e ) {
        Average = numbers.Average();
    }
}

The ListNofityChanged<T> class is a collection class that closely resembles the List<T> class. However, it fires change notifications events when items are added or removed from the list.

Here is the full implementation of ListNofityChanged<T>

/// <summary>
/// A generic list that will notify when there are
/// changes made to the list.
/// </summary>
public class ListNotifyChanged<T> : IList<T> {
    IList<T> list = new List<T>();

    public ListNotifyChanged() { }

    public ListNotifyChanged( int capacity ) {
        list = new List<T>(capacity);
    }

    public ListNotifyChanged( IList<T> list ) {
        this.list = list;
    }

    public ListNotifyChanged( IEnumerable<T> collection ) {
        list = new List<T>(collection);
    }

    public event EventHandler<ListChangedEventArgs> Changed;
    public event EventHandler<EventArgs> Cleared;

    protected virtual void OnChanged( ListChangedEventArgs e ) {
        if (Changed != null) Changed(this, e);
    }

    protected virtual void OnCleared() {
        if (Cleared != null) Cleared(this, new EventArgs());
    }

    #region IList<T> Members

    public T this[int index] {
        get { return list[index]; }
        set {
            list[index] = value;
            OnChanged(new ListChangedEventArgs(index, value));
        }
    }

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

    public void Insert( int index, T item ) {
        list.Insert(index, item);
        OnChanged(new ListChangedEventArgs(index, item));
    }

    public void RemoveAt( int index ) {
        T item = list[index];
        list.Remove(item);
        OnChanged(new ListChangedEventArgs(index, item));
    }

    #endregion

    #region ICollection<T> Members
    public void Add( T item ) {
        list.Add(item);
        OnChanged(new ListChangedEventArgs(list.IndexOf(item), item));
    }

    public void Clear() {
        list.Clear();
        OnCleared();
    }

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

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

    public int Count {
        get { return list.Count; }
    }

    public bool IsReadOnly {
        get { return list.IsReadOnly; }
    }

    public bool Remove( T item ) {
        int index = list.IndexOf(item);
        if (list.Remove(item)) {
            OnChanged(new ListChangedEventArgs(index, item));
            return true;
        }
        else
            return false;
    }
    #endregion

    #region IEnumerable<T> Members

    public IEnumerator<T> GetEnumerator() {
        return list.GetEnumerator();
    }

    #endregion

    #region IEnumerable Members

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

    #endregion

    public class ListChangedEventArgs : EventArgs {
        public int index;
        public T item;
        public ListChangedEventArgs( int index, T item ) {
            this.index = index;
            this.item = item;
        }
    }
}