c#:foreach、IEnumrator、yield的理解

GPU小码农 2014-01-09 11:33:16
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
namespace yield_learn
{
public class person : System.Collections.IEnumerable
{
#region IEnumerable
public string x = "cc";
public System.Collections.IEnumerator GetEnumerator()
{
yield return "1";
Thread.Sleep(3000);
yield return "2";
Thread.Sleep(3000);
yield return "3";
Thread.Sleep(3000);
yield return "4";
Thread.Sleep(3000);
yield return "5";
Thread.Sleep(3000);
yield return "6";

}//是如何选择遍历哪个的??
public System.Collections.IEnumerator getnum()
{
yield return "dshdjs";//为什么没有输出这个??
}
#endregion
}
class Program
{
static void Main(string[] args)
{
person arrperson = new person();
foreach (string s in arrperson)//遍历一个类中的string吗,必须带有System.Collections.IEnumerator的才遍历,但是为什么第二个不遍历呢?
{
System.Console.WriteLine(s);
}
System.Console.ReadLine();
}
}
}
...全文
402 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
引用 2 楼 huiguimoyu 的回复:
但是为什么没有输出第28行的字符串呢?和第一个函数基本完全一样啊?!
getnum()返回的对象需要具有一个返回相应类型的 GetEnumerator() 方法,这是在语法上这样规定的。
qldsrx 2014-01-13
  • 打赏
  • 举报
回复
引用 8 楼 sp1234 的回复:
[quote=引用 7 楼 caozhy 的回复:] http://bbs.csdn.net/topics/390636800
嗯,试了一下确实如此,这是语法糖,确实不需要 IEnumerable 接口。
public class person
{
    public A getnum()
    {
        return new A();
    }
}

public class A
{
    public System.Collections.IEnumerator GetEnumerator()
    {
        yield return "dshdjs";//为什么没有输出这个??
    }
}
这可以支持 foreach (string s in arrperson.getnum()) 操作[/quote] 这是有历史原因的,为了支持数组等运行时添加扩展方法的类,不得已违背了接口的模式,但是通过接口来定义能更加清晰自己必须要实现的方法。
  • 打赏
  • 举报
回复
引用 7 楼 caozhy 的回复:
http://bbs.csdn.net/topics/390636800
嗯,试了一下确实如此,这是语法糖,确实不需要 IEnumerable 接口。
public class person
{
    public A getnum()
    {
        return new A();
    }
}

public class A
{
    public System.Collections.IEnumerator GetEnumerator()
    {
        yield return "dshdjs";//为什么没有输出这个??
    }
}
这可以支持 foreach (string s in arrperson.getnum()) 操作
NotNull 2014-01-13
  • 打赏
  • 举报
回复
GetEnumeratorz就是给这个继承的集合赋值! 这样就输出所有的值了!

           person arrperson = new person();
            System.Console.WriteLine(arrperson.x);
            foreach (string s in arrperson)
            {
                System.Console.WriteLine(s);
            }
            foreach (string s in arrperson.getnum())
            {
                System.Console.WriteLine(s);
            }
            System.Console.ReadLine();
threenewbee 2014-01-12
  • 打赏
  • 举报
回复
http://bbs.csdn.net/topics/390636800
  • 打赏
  • 举报
回复
引用 5 楼 huiguimoyu 的回复:
那请问下如果要结合foreach调用getnum()函数该怎么写呢?我写的:foreach (string s in arrperson.getnum())报错!
哎, 你到底有没有看明白所有的回复呢? 你的getnum()返回的对象实现了IEnumerable接口了吗?它不过是实现了IEnumerator接口而已好不好?!
GPU小码农 2014-01-12
  • 打赏
  • 举报
回复
引用 4 楼 qldsrx 的回复:
你去看下IEnumerable接口的定义,你再试试把GetEnumerator()函数删除是否会报错。GetEnumerator()是必须有的,而getnum()是可有可无的,foreach遍历只会使用必须存在的而不是可有可恶的方法,不是看返回值类型符合就会去用,而是看是否满足接口的规范。
那请问下如果要结合foreach调用getnum()函数该怎么写呢?我写的:foreach (string s in arrperson.getnum())报错!
本拉灯 2014-01-09
  • 打赏
  • 举报
回复
引用 楼主 huiguimoyu 的回复:
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
namespace yield_learn
{
    public class person : System.Collections.IEnumerable
    {
        #region IEnumerable
        public string x = "cc";
        public System.Collections.IEnumerator GetEnumerator()
        {
            yield return "1";
            Thread.Sleep(3000);
            yield return "2";
            Thread.Sleep(3000);
            yield return "3";
            Thread.Sleep(3000);
            yield return "4";
            Thread.Sleep(3000);
            yield return "5";
            Thread.Sleep(3000);
            yield return "6";

        }//是如何选择遍历哪个的??
        public System.Collections.IEnumerator getnum()
        {
            yield return "dshdjs";//为什么没有输出这个??
        }
        #endregion
    }
    class Program
    {
        static void Main(string[] args)
        {
            person arrperson = new person();
            foreach (string s in arrperson)//遍历一个类中的string吗,必须带有System.Collections.IEnumerator的才遍历,但是为什么第二个不遍历呢?
            {
                System.Console.WriteLine(s);
            }
            System.Console.ReadLine();
        }
    }
}
IEnumerable 用于foreach IEnumerator 用于while(xxx.MoveNext()) 明白了没。两个不一样。
qldsrx 2014-01-09
  • 打赏
  • 举报
回复
你去看下IEnumerable接口的定义,你再试试把GetEnumerator()函数删除是否会报错。GetEnumerator()是必须有的,而getnum()是可有可无的,foreach遍历只会使用必须存在的而不是可有可恶的方法,不是看返回值类型符合就会去用,而是看是否满足接口的规范。
本拉灯 2014-01-09
  • 打赏
  • 举报
回复
引用 2 楼 huiguimoyu 的回复:
但是为什么没有输出第28行的字符串呢?和第一个函数基本完全一样啊?!
foreach (string s in arrperson) 这个只会调用 GetEnumerator() 这个方法不会调用 getnum() 明白了没。
GPU小码农 2014-01-09
  • 打赏
  • 举报
回复
但是为什么没有输出第28行的字符串呢?和第一个函数基本完全一样啊?!

110,567

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧