Here are two proof of concepts in one.
Ontopic one first:
All foreach needs is an object that implements IEnumberable. This means you are never guaranteed the object is indexable, or even know how many iterations will take place before the loop starts. As an example here is a program that uses foreach to write numbers from an object that just generates random numbers. The foreach will randomly terminate when a random number <= 20 is generated. There could be actual data structures where indexes don't make sense either.
Second thing this code shows:
The way I generate a series of random numbers is actually not random at all. Creating Random objects real close to each other will actually use the same seed and you will get a sequence of the exact same numbers if using the same range. So say you have a class for mobs that start with semi random stats. If they all create their own random number generator they will be a high chance they will start with the same stats. The correct way to do it is use a static random object (the commented out way) This way a new seed is used for each new random number since the .Next method generates a new seed.
Code:
using System;
using System.Collections.Generic;
using System.Text;
using System.Collections;
namespace RandomNums
{
public class RandomNums : IEnumerable
{
static Random rand = new Random();
public IEnumerator GetEnumerator()
{
return new RandEnumerator();
}
public class RandEnumerator : IEnumerator
{
int number;
public object Current
{
get { return number; }
}
public bool MoveNext()
{
return ((number = new Random().Next(100)) > 20);
//return ((number = rand.Next(100)) > 20);
}
public void Reset() { }
}
}
class Program
{
static void Main(string[] args)
{
RandomNums myRands = new RandomNums();
foreach (int num in myRands)
{
Console.WriteLine(num);
}
}
}
}