Gear.Turbo

你是如何让函数返回IEnumerable<T>的

为什么让接口返回IEnumerable<T>

关于这个问题不需要过多的解释,且不是本文讨论的重点。简单来说,遵循接口最小原则,返回用户最少的行为即可。因此,能返回IEnumerable<T>则不返回List<T>或Collection<T>。

接口的实现函数如何返回IEnumerable<T>

一个最简单的方法,也是程序代码中经常见同事的做法是在函数中创建一个List<T>,然后对其进行赋值,最后作为函数返回值来返回。

这种做法完全正确,而且List<T>太好用了,以至于我们可以用它来解决大部分问题,一个简单而典型的例子如下(例子本身没有啥意思,仅作演示之用):

IEnumerable<string> GetStrings()
{
    List<string> list = new List<string>();
    for (int i = 0; i < 10; i++)
    {
        list.Add(i.ToString());
    }

    return list;
}

然而,在任意创建一个List<T> 之前,或许存在某种更简单或更优雅的方法。

yield return 生成IEnumerable<T>

yield return 是C#的一个关键字,两者必须结合在一起使用,表示生成IEnumerable<T>的一个元素。因此,很多情况下yield return可以让我们减少新创建List<T>的几率。基于yield return,前面的例子可以修改如下:

IEnumerable<string> GetStrings()
{
    for (int i = 0; i < 10; i++)
    {
        yield return i.ToString();
    }
}

如此,程序则“优雅”许多。

如何生成一个空的IEnumerable<T>

经常见到的一些例子是生成一个空的List<T> 然后返回之。举例如下:

IEnumerable<string> GetStrings()
{
    return new List<string>();
}

代码没任何问题,但总有那么点别扭:一个空的List<T>似乎生成的没必要。事实上,C#也为这种情况作了“优雅”的设计:

IEnumerable<string> GetStrings()
{
    yield break;
}

对,没错!就是yield break,一个简单的关键字让程序“优雅”。事实上,yield return 和yield break结合起来可以处理复杂的逻辑,从而轻松的让函数返回IEnumerable<T>而尽量减少不必要的List<T>的中间变量。

一点观点

不要对语法糖抱有太多的成见,只要好用,为什么不去用呢?糖放在那儿,有谁不喜欢吃呢?

posted on 2011-08-28 19:54  lsp  阅读(2348)  评论(2编辑  收藏  举报

导航