C# 在开展foreach时出现不包含MoveNext的定义

C# 在进行foreach时出现不包含MoveNext的定义
  已经定义啦!using System.Collections;
            primes pF = new primes(2, 1100);
            foreach (long i in pF)
             Console.Write("{0}", i);
     在foreach出现时出现不包含MoveNext的定义。
错误 1 foreach 要求“ch1103.primes.GetEnumerator()”的返回类型“System.Collections.IEnumerable”必须具有适当的公共 MoveNext 方法和公共 Current 属性 D:\Documents\Visual Studio 2010\Projects\C#\ch1101\ch1103\Program.cs 68

------解决思路----------------------
primes 这个类型怎么定义的
------解决思路----------------------
foreach只能遍历实现了IEnumerable接口的类,如int[],List<T>,IEnumerable<T>等等,
你要让primes实现IEnumerable,或者在primes类中添加一个long[]属性,
再用foreach遍历这个属性

primes pF = new primes(2, 1100);
long[] ps=pF.GetLongs;
  foreach (long i in ps)
  Console.Write("{0}", i);

------解决思路----------------------
foreach使用的类也不一定必须继承IEnumerable接口,但必须具有GetEnumerator()的方法实现,该方法实现返回值又必须为具有Current的属性和实现MoveNext()的方法的类的实例,编译器称这个概念为“Duck typing”,来自于英语俗语“如果走起路来像鸭子,叫起来像鸭子,那么肯定是一只鸭子”,就是长得像就OK。

    class Program
    {
        static void Main(string[] args)
        {
            MyClass myClass = new MyClass();
            foreach (int intDemo in myClass)
            {
                Console.WriteLine(intDemo);
            }

            Console.ReadLine();
        }
    }

    class MyClass
    {
        private Stack<int> stack = new Stack<int>();
        private Stack<int>.Enumerator enumerator = new Stack<int>.Enumerator();
        
        public MyClass()
        {
            stack.Push(1);
            stack.Push(2);
        }

        public IEnumerator<int> GetEnumerator()
        {
            enumerator = this.stack.GetEnumerator();
            return enumerator;
        }
    }

------解决思路----------------------
有点tricky:

一下来自msdn:
在 C# 中,集合类并非必须严格从 IEnumerable 和 IEnumerator 继承才能与 foreach 兼容;只要类有所需的 GetEnumerator、MoveNext、Reset 和 Current 成员,便可以与 foreach 一起使用。省略接口的好处为,使您可以将 Current 的返回类型定义得比 object 更明确,从而提供了类型安全。

详细信息请阅读:
如何:使用 foreach 访问集合类(C# 编程指南)
http://msdn.microsoft.com/zh-cn/library/9yb8xew9(v=vs.80).aspx
------解决思路----------------------
3#正解,这种现象在.NET中比较普遍
比如集合初始化器也是使用任意可访问的公共Add函数,并不需要是IList.Add
await也是可以用于任何实现了所需成员的类型上,这些成员不属于某个接口

还有编译器对foreach有优化,并不一定会使用MoveNext和Current来实现
------解决思路----------------------
而且这些函数即使是扩展函数也行