1

方法一:

class myClass
{
   List<SomeType> _list;

   IENumerator<SomeType> GetEnumerator()
   {
      foreach(SomeType t in _list)
        yield return t;
   }
}

myClass m = new myClass();
List<SomeType> list;
...
foreach(SomeType t in m)
  list.Add(t);

方法二:

class myClass
{
    public List<SomeType> _list {get; private set;}
}

myClass m = new myClass();
...
List<SomeType> list = m.list;

哪种方法更好?如果是第二个,那么你能告诉我收益回报的真实使用吗?

4

3 回答 3

3

两者都不。

如果你想要一个枚举器,并且已经有一个底层IEnumerable类型(Listimplements IListwhich extends IEnumerable),那么就这样返回它:

public IEnumerator<SomeType> GetEnumerator ()
{
    return _list.GetEnumerator();
}

否则,如果您确实需要一个列表,即使用索引进行随机访问,则返回一个IList; 如果你真的想返回它的内部实现类型, ie List,那么你可以让它成为一个可访问的属性。但请注意,私有设置器不会阻止修改列表(添加或删除项目等)。如果需要,请改为返回只读列表:

public IList<SomeType> List
{
    get { return _list.AsReadOnly(); }
}

关于产量

你能告诉我收益回报的真实使用吗?

yield return很有用,当您实际上有一个生成器时,当您实际需要生成下一个项目时。一个简单的例子是一个随机数生成器,只要你不断询问它,它就会为你提供另一个随机数。它不一定有结束,但在开始之前你可能不知道数字的数量。

另一个常见的用法是从某个外部源检索数据的任何东西。例如来自网络服务的项目列表。在您不知道有多少项目之前,您不一定知道您实际需要多少项目(因为您可能希望以无休止的方式显示它,一次显示一个)。在这种情况下,您可以这样做:

IEnumerable<Item> GetItems()
{
    while (Service.HasMorePages())
    {
        foreach (Item item in Service.GetNextPage())
        {
            yield return item;
        }
    }
    yield break;
}

GetNextPage将始终一次返回一个N项目列表,并且只要您想要的项目多于您已经收到的项目,您就会得到下一个。

于 2012-11-22T14:25:42.580 回答
3

具有集合属性的类通常最好以列表的形式完成,这样它就可以多次迭代和变异。这对于仅代表一个序列的枚举器是不可能的。枚举器的典型用途可能是:

  • 动态过滤数据(例如Enumerable.Where
  • 从包含多条记录的文件中顺序读取单个项目,而不是一次全部加载
    • 或网络套接字
    • 或数据库服务器
  • 在数据序列上提供一个只转发、只读的包装器
  • ETC
于 2012-11-22T14:26:03.337 回答
1

选项没有限制,

public IEnumerator<int> FibonnaciSeries()
{
    int a = 1;
    int b = 1;

    yield return 1;
    yield return 1;

    while (true)
    {
        var c = a + b;
        a = b;
        b = c;
        yield return c;
    }
}

想到一个简单的例子,斐波那契数列是真实世界吗?


这不是最有效的实现方式。

于 2012-11-22T14:35:24.543 回答