Several interrelated issues in one.
Question 1: Suppose there is an indexable collection that also implements access to its elements through an iterator. Is the iterator of such a collection required to return elements in ascending order of the index? Ie, let's say, here is such a collection-wrapper:
class Shuffle<T> : IReadOnlyList<T> { IReadOnlyList<T> _internal; public int Count { get { return _internal.Count; } } public T this[int i] { get { return _internal[i]; } } public Shuffle(IReadOnlyList<T> elements) { if (elements == null) throw new ArgumentNullException(); _internal = elements; } public IEnumerator<T> GetEnumerator() { Random rnd = new Random(); List<int> indexes = new List<int>(_internal.Count); indexes.AddRange(Enumerable.Range(0, _internal.Count)); while (indexes.Count > 0) { int i = rnd.Next(indexes.Count); int ix = indexes[i]; indexes.RemoveAt(i); yield return _internal[ix]; } } IEnumerator IEnumerable.GetEnumerator() { return _internal.GetEnumerator(); } } will it violate any generally accepted standards?
Question 2: When working with standard collections, such as T[] or List<T> , if the order of access to the elements of the collection is important , can you, without fear (*), replace such a construction
char[] ch_arr = new char[] { 'A', 'B', 'C' }; for (int i = 0; i < ch_arr.Length; i++) Console.Write(ch_arr[i]); on this:
char[] ch_arr = new char[] { 'A', 'B', 'C' }; foreach (char c in ch_arr) Console.Write(c); ?
(*) - the following, for example, script. The kernel update has been released, the memory for the array is no longer allocated in one piece, but can be allocated by blocks, the implementation of the iterator for the array (for speed) has been changed, and the elements can now be returned not in a logical order, but in some arbitrary. Or today we write for one platform, and tomorrow this code needs to be transferred to another, where there is such a feature.