Should we initialize List(T) with size if known ?

As per documentation, it says

If the size of the collection can be estimated, specifying the initial capacity eliminates the need to perform a number of resizing operations while adding elements to the List.

We can decrease the capacity of a List(T) any time by calling TrimExcess method over the List(T).
If we decrease the capacity, interestingly, it is not decreased, but the memory is relocated and all the elements in the List(T) are copied into that memory location.

dafault capacity if not defined is “0”. A List doubles itself, every time the capacity limit is hit.

Capacity for the List could be checked easily, any time using List(T).Capacity property.

           List<string> animals = new List<string>();

            animals.Add("cow");
            animals.Add("bull");           

            // get List<string> capacity
            int listCapacity = animals.Capacity;
          
            // get List<string> size
            int listSize = animals.Count;

            // reduce capacity 
            animals.TrimExcess();

            // make Lis<string> empty
            animals.Clear(); 

Implement System.Collections.IList Interface using C#

Today we will look into the interface System.Collections.IList and some of the its methods. A very good example is for IList implementation in use any class Inheriting from IList or ArraList class itself. Following is ArrayList Signature as on MSDN.

public class ArrayList : IList, ICollection, IEnumerable, ICloneable

To start with, let’s derive a simple class from IList

public class ListImpl : IList
{ 
 private object[] _contents = new object[8];
}

We need to implement all members defined in the IList interface and and the interfaces: ICollection and IEnumerable as IList derives from these interfaces. Following is CopyTo Method from ICollection interface.

        public void CopyTo(Array array, int index)
        {
            int j = index;
            for (int i = 0; i < Count; i++)
            {
                array.SetValue(_contents[i], j);
                j++;
            }
        }

Following is GetEnumerator method from IEnumerable interface.

public IEnumerator GetEnumerator()
{
  // Refer to the IEnumerator documentation another sample
  return (_contents as IEnumerable).GetEnumerator();
}

Here are some other methods and properties

      private int _count;
      public int Count
      {
            get
            {
                return _count;
            }
       }

       // Add an object to the List
       public int Add(object value)
       {
           if (_count < _contents.Length)
           {
               _contents[_count] = value;
               _count++;

               return (_count - 1);
           }
           else
           {
                return -1;
           }
       }

       // Clear the List
       public void Clear()
        {
            _count = 0;
        }

       // Check if the List contains some value
       public bool Contains(object value)
        {
            bool inList = false;
            for (int i = 0; i < Count; i++)
            {
                if (_contents[i] == value)
                {
                    inList = true;
                    break;
                }
            }
            return inList;
        }

       // Check if List is fixed size
       public bool IsFixedSize
        {
            get
            {
                return true;
            }
        }

        // Overriding ToString() Method
        public override string ToString()
        {
            StringBuilder sb = new StringBuilder();
            foreach (object o in _contents)
            {
                sb.Append(o.ToString());
            }
            return sb.ToString();
        }

We need to provide implementation for following methods as per requirements.


        public int IndexOf(object value)
        {
            throw new NotImplementedException();
        }

        public void Insert(int index, object value)
        {
            throw new NotImplementedException();
        }

        public bool IsReadOnly
        {
            get { throw new NotImplementedException(); }
        }

        public void Remove(object value)
        {
            throw new NotImplementedException();
        }

        public void RemoveAt(int index)
        {
            throw new NotImplementedException();
        }

        public object this[int index]
        {
            get
            {
                throw new NotImplementedException();
            }
            set
            {
                throw new NotImplementedException();
            }
        }

        public bool IsSynchronized
        {
            get { throw new NotImplementedException(); }
        }

        public object SyncRoot
        {
            get { throw new NotImplementedException(); }
        }