Yes, there is CLR 2.0 now, with C# 2.0 generics and iterators. Yet, the more design tools for your professional designer’s toolbox, the better.Implementing global::System.Collections.IEnumerable and global::System.Collections.IEnumerator implies some necessary performance costs due boxing and unboxing operations since IEnumerator.Current property returns global::System.Object type, and "Even if the collection contains reference types, you still incur the penalty of the down-casting from Object".There is an alternative since C# 1.0: design your classes with the same methods as the above interfaces but returning the case-specific type, the CLR will invoke yours as expected, here is a simple example:class T { private string[] strs; public T(string[] s) { strs = s; } public S GetEnumerator() { return new S(this); } public class S { private T t; private int index; public S(T x) { t = x; index = -1; } public bool MoveNext() { ++index; return index < t.strs.Length; } public string Current { get { return t.strs[index]; } } } } class exe { static T g() { return new T(new string[] { "zero", "one", "two" }); } static void Main() { foreach (object x in g()) System.Console.WriteLine(x); } }
class T { private string[] strs; public T(string[] s) { strs = s; } public S GetEnumerator() { return new S(this); } public class S { private T t; private int index; public S(T x) { t = x; index = -1; } public bool MoveNext() { ++index; return index < t.strs.Length; } public string Current { get { return t.strs[index]; } } } } class exe { static T g() { return new T(new string[] { "zero", "one", "two" }); } static void Main() { foreach (object x in g()) System.Console.WriteLine(x); } }