什么具体类型'收益率'回报?

时间:2010-08-11 00:04:57

标签: c# ienumerable yield-return

IEnumerable<string>的具体类型是什么?

private IEnumerable<string> GetIEnumerable()
{
    yield return "a";
    yield return "a";
    yield return "a";
}

3 个答案:

答案 0 :(得分:8)

这是编译器生成的类型。编译器生成一个IEnumerator<string>实现,它返回三个“a”值和一个IEnumerable<string>骨架类,它在GetEnumerator方法中提供其中一个。

生成的代码看起来像这样的 *:

// No idea what the naming convention for the generated class is --
// this is really just a shot in the dark.
class GetIEnumerable_Enumerator : IEnumerator<string>
{
    int _state;
    string _current;

    public bool MoveNext()
    {
        switch (_state++)
        {
            case 0:
                _current = "a";
                break;
            case 1:
                _current = "a";
                break;
            case 2:
                _current = "a";
                break;
            default:
                return false;
        }

        return true;
    }

    public string Current
    {
        get { return _current; }
    }

    object IEnumerator.Current
    {
        get { return Current; }
    }

    void IEnumerator.Reset()
    {
        // not sure about this one -- never really tried it...
        // I'll just guess
        _state = 0;
        _current = null;
    }
}

class GetIEnumerable_Enumerable : IEnumerable<string>
{
    public IEnumerator<string> GetEnumerator()
    {
        return new GetIEnumerable_Enumerator();
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }
}
或许,正如SLaks在他的回答中所说,这两个实现最终都在同一个类中。我根据我之前看过的生成代码的不稳定记忆写了这个;实际上,一个类就足够了,因为上述功能没有理由需要两个。

实际上,考虑到它,两个实现应该属于单个类,因为我只记得使用yield语句的函数必须具有返回类型 IEnumerable<T> IEnumerator<T>

无论如何,我会让你对我在精神上发布的内容进行代码更正。

*这纯粹是为了说明目的;我没有声称它的真实准确性。根据我在自己的调查中看到的证据,它只是以一般方式展示编译器如何做它的作用。

答案 1 :(得分:7)

编译器将自动生成一个实现IEnumerable<T>IEnumerator<T>的类(在同一个类中)。

Jon Skeet has a detailed explanation

答案 2 :(得分:2)

该方法返回的IEnumerable<string>的具体实现是编译器生成的匿名类型

Console.WriteLine(GetIEnumerable().GetType());

打印:

YourClass+<GetIEnumerable>d__0