‘yield 返回’的具体类型是什么?返回?

发布于 2024-09-13 23:19:35 字数 208 浏览 8 评论 0原文

这个 IEnumerable 的具体类型是什么?

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

What is the concrete type for this IEnumerable<string>?

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

划一舟意中人 2024-09-20 23:19:35

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

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

// 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 IEnumerator

不管怎样,我会让你对我在心里发布的内容进行代码更正。

*这纯粹是为了说明目的;我不保证其真实准确性。这只是根据我在自己的调查中看到的证据,以一般方式演示编译器如何执行其操作。

It's a compiler-generated type. The compiler generates an IEnumerator<string> implementation that returns three "a" values and an IEnumerable<string> skeleton class that provides one of these in its GetEnumerator method.

The generated code looks something like this*:

// 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();
    }
}

Or maybe, as SLaks says in his answer, the two implementations end up in the same class. I wrote this based on my choppy memory of generated code I'd looked at before; really, one class would suffice, as there's no reason the above functionality requires two.

In fact, come to think of it, the two implementations really should fall within a single class, as I just remembered the functions that use yield statements must have a return type of either IEnumerable<T> or IEnumerator<T>.

Anyway, I'll let you perform the code corrections to what I posted mentally.

*This is purely for illustration purposes; I make no claim as to its real accuracy. It's only to demonstrate in a general way how the compiler does what it does, based on the evidence I've seen in my own investigations.

梦在夏天 2024-09-20 23:19:35

编译器将自动生成一个同时实现 IEnumerableIEnumerator(在同一个类中)的类。

Jon Skeet 有详细的解释

The compiler will automatically generate a class that implements both IEnumerable<T> and IEnumerator<T> (in the same class).

Jon Skeet has a detailed explanation.

‖放下 2024-09-20 23:19:35

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

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

Prints :

YourClass+<GetIEnumerable>d__0

The concrete implementation of IEnumerable<string> returned by the method is an anonymous type generated by the compiler

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

Prints :

YourClass+<GetIEnumerable>d__0
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文