B
B
BadCats2016-09-17 22:59:44
C++ / C#
BadCats, 2016-09-17 22:59:44

Yield and flows?

class UserCollection
    {
        public static IEnumerable Power()
        {
            yield return "Hello world!";
        }
    }

.Net Reflector yield statement - ported to C# and Visual Studio ralia
class UserCollection
    {
        public static IEnumerable Power()
        {
            return new ClassPower(-2);
        }
 
        private sealed class ClassPower : IEnumerable<object>,  IEnumerator<object>, IEnumerator, IDisposable
        {
            // Поля.
            private int state;
            private object current;
            private int initialThreadId;
 
            // Конструктор.
            public ClassPower(int state)
            {
                this.state = state;
                this.initialThreadId = Thread.CurrentThread.ManagedThreadId;
            }
 
            //private bool IEnumerator.MoveNext() // Так в Рефлекторе
            bool IEnumerator.MoveNext()
            {
                switch (this.state)
                {
                    case 0:
                        this.state = -1;
                        this.current = "Hello world!";
                        this.state = 1;
                        return true;
 
                    case 1:
                        this.state = -1;
                        break;
                }
                return false;
            }
 
            IEnumerator<object> IEnumerable<object>.GetEnumerator()
            {
                if ((Thread.CurrentThread.ManagedThreadId == this.initialThreadId) && (this.state == -2))
                {
                   this.state = 0;
                   return this;
                }
                return new UserCollection.ClassPower(0);
            }
 
            IEnumerator IEnumerable.GetEnumerator()
            {
                // Так в Рефлекторе 
                //return this.System.Collections.Generic.IEnumerable<System.Object>.GetEnumerator(); 
                
                return (this as IEnumerable<object>).GetEnumerator();
            }
 
            void IEnumerator.Reset()
            {
                throw new NotSupportedException();
            }
 
            void IDisposable.Dispose()
            {
            }
 
            // Свойства.
            object IEnumerator<object>.Current
            {
                get
                {
                    return this.current;
                }
            }
 
            object IEnumerator.Current
            {
                get
                {
                    return this.current;
                }
            }
        }
    }

I'm interested in the line and how the author comments on it
this.initialThreadId = Thread.CurrentThread.ManagedThreadId;

this string indicates synchronization and access to this collection as a shared resource.
Why is it that when working with yield, the collection is perceived as a shared resource and why work with threads is needed in general?

Answer the question

In order to leave comments, you need to log in

1 answer(s)
R
Roman, 2016-09-18
@BadCats

Not really, it looks from which thread it is called and, if necessary, another enumerator (Enumerator) is returned, just if you have a collection enumeration in several threads, then in one thread you will not get the entire collection, just before calling Current, the method can be called MoveNext.
It is better to make Enumerator a private inner class. In principle, it is not even necessary to make it an implementation of an interface. just the MoveNext method and the Current property are enough.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question