I had the same idea as Jon Skeet : implement a wrapper around T[] that provides random access by index, automatically processing the indexed access setting for you.
I recently put together a quick implementation (skip to the end of this answer for a short demonstration):
public struct ArrayFragment<T> : IList<T> { private T[] _source; private int _start; private int _count; public ArrayFragment(T[] source, int start, int count) { if (source == null) { throw new ArgumentNullException("source"); } if (start < 0 || start >= source.Length) { throw new ArgumentOutOfRangeException("start"); } if (count > source.Length - start) { throw new ArgumentOutOfRangeException("count"); } _source = source; _start = start; _count = count; } public T this[int index] { get { return _source[_start + index]; } } public int Count { get { return _count; } } public bool Contains(T value) { int index = Array.IndexOf(_source, value, _start, _count); return index != -1; } public void CopyTo(T[] destination, int index) { Array.Copy(_source, _start, destination, index, _count); } public int IndexOf(T value) { int index = Array.IndexOf(_source, value, _start, _count); return index != -1 ? index - _start : -1; } public IEnumerator<T> GetEnumerator() { for (int i = 0; i < _count; ++i) { yield return _source[_start + i]; } } #region Explicit Interface Implementation // a bunch of explicitly implemented IList<T> members // that all throw a NotSupportedException #endregion }
Here is a demo:
int[] numbers = new[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 }; try { var fragment = new ArrayFragment<int>(numbers, 2, 5); Console.WriteLine("Iterating using foreach: "); foreach (int number in fragment) { Console.WriteLine(number); } Console.WriteLine("Iterating using for: "); for (int i = 0; i < fragment.Count; ++i) { Console.WriteLine(fragment[i]); } Console.WriteLine("Index of 4: {0}", fragment.IndexOf(4)); Console.WriteLine("Index of 1: {0}", fragment.IndexOf(1)); Console.WriteLine("Index of 9: {0}", fragment.IndexOf(9)); Console.WriteLine("Index of 7: {0}", fragment.IndexOf(7)); } catch (Exception ex) { Console.WriteLine(ex.ToString()); } Console.ReadLine();
Output:
Iterating using foreach:
3
four
5
6
7
Iterating using for:
3
four
5
6
7
Index of 4: 1
Index of 1: -1
Index of 9: -1
Index of 7: 4
Dan Tao Aug 30 '10 at 19:59 2010-08-30 19:59
source share