What concrete type does 'yield return' return?

后端 未结 3 1063
谎友^
谎友^ 2020-12-19 00:56

What is the concrete type for this IEnumerable?

private IEnumerable GetIEnumerable()
{
    yield return \"a\";
    y         


        
3条回答
  •  没有蜡笔的小新
    2020-12-19 01:47

    It's a compiler-generated type. The compiler generates an IEnumerator implementation that returns three "a" values and an IEnumerable 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
    {
        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
    {
        public IEnumerator 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 or IEnumerator.

    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.

提交回复
热议问题