Collections Data Structure C#

//http://isotopescreencapture.codeplex.com/
//The MIT License (MIT)
using System.Collections.Generic;
namespace Isotope.Collections
{
    public class ChunkedList : IEnumerable.RowEnumerator>
    {
        private readonly List data;
        private readonly int _chunkSize;
        public ChunkedList(int chunksize, int capacity)
        {
            if (chunksize < 1)
            {
                throw new System.ArgumentOutOfRangeException("chunksize", "must be at least 1");
            }
            this._chunkSize = chunksize;
            this.data = new List(chunksize * capacity);
        }
        public T[] ToArray()
        {
            return this.data.ToArray();
        }
        public void Add(params T[] items)
        {
            this.AddChunk(items);
        }
        public void AddChunk(ICollection items)
        {
            if (items.Count != _chunkSize)
            {
                string msg = string.Format("must add exactly {0} items", items.Count);
                throw new System.ArgumentOutOfRangeException(msg);
            }
            this.data.AddRange(items);
            if (this.data.Count % this._chunkSize != 0)
            {
                throw new System.Exception("Did not maintain consistency of chunked list");
            }
        }
        public int Count
        {
            get
            {
                return this.data.Count / this._chunkSize;
            }
        }
        public int ChunkSize
        {
            get { return _chunkSize; }
        }
        public void GetRow(int r, T[] row_array)
        {
            int startindex = r * this._chunkSize;
            for (int c = 0; c < this._chunkSize; c++)
            {
                row_array[c] = this.data[startindex + c];
            }
        }
        public T[] GetRow(int r)
        {
            var a = new T[this._chunkSize];
            this.GetRow(r, a);
            return a;
        }
        public T this[int row, int col]
        {
            get
            {
                if (row < 0)
                {
                    throw new System.ArgumentOutOfRangeException("row", "must be greater than zero");
                }
                if (col < 0)
                {
                    throw new System.ArgumentOutOfRangeException("col", "must be greater than zero");
                }
                if (row >= this.Count)
                {
                    throw new System.ArgumentOutOfRangeException("row");
                }
                if (col >= this._chunkSize)
                {
                    throw new System.ArgumentOutOfRangeException("col");
                }
                return this.data[(row * this._chunkSize) + col];
            }
        }
        // Implement IEnumerable
        System.Collections.Generic.IEnumerator
            System.Collections.Generic.IEnumerable.GetEnumerator()
        {
            return this.AsEnumerable().GetEnumerator();
        }
        // Implement IEnumerable
        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
        {
            return this.AsEnumerable().GetEnumerator();
        }
        private T[] CreateRowBuffer()
        {
            var row = new T[this._chunkSize];
            return row;
        }
        private IEnumerable AsEnumerable()
        {
            var row_array = this.CreateRowBuffer();
            for (int r = 0; r < this.Count; r++)
            {
                this.GetRow(r, row_array);
                yield return new RowEnumerator(r, row_array);
            }
        }
        public struct RowEnumerator
        {
            public readonly int Index;
            public readonly T[] ItemArray;
            internal RowEnumerator(int index, T[] itemarray)
            {
                this.Index = index;
                this.ItemArray = itemarray;
            }
        }
    }
}