收益率回报率

时间:2012-11-22 14:17:42

标签: c# yield-return

方法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);

方法2:

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

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

哪种方法更好?如果第二,那么请你告诉我收益率回报的实际用法吗?

3 个答案:

答案 0 :(得分:3)

都不是。

如果你想要一个枚举器,并且已经有一个基础IEnumerable类型(List实现IList扩展IEnumerable),那么就这样返回:

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

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

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

关于产量

  

你能告诉我收益率回报的真实证据吗?

当您实际拥有生成器时,

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

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

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

GetNextPage总是会一次返回N个项目列表,只要您想要的项目数量超过您收到的项目,就会获得下一个项目。

答案 1 :(得分:3)

具有集合属性的类通常最好作为列表完成,以便可以多次迭代并进行变异。对于只表示序列的枚举器而言,这是不可能的。枚举器的典型用途可能是:

  • 即时过滤数据(例如Enumerable.Where
  • 从包含多个记录的文件中顺序读取单个项目,而不是一次性加载所有项目
    • 或网络套接字
    • 或数据库服务器
  • 在数据序列上提供仅向前,只读的包装器

答案 2 :(得分: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;
    }
}

想到一个微不足道的例子,是Fibonnaci系列真实世界吗?


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