/// <summary>
        /// Convert an IteratorState to an instance of the iterator it represents.
        /// </summary>
        /// <param name="state">An IteratorState instance.</param>
        /// <returns>An equivalent iterator instance.</returns>
        public IEnumerator FromState(IteratorState state)
        {
            if (state == null)
                throw new ArgumentNullException(nameof(state));

            Type iteratorType = GetIteratorTypeChecked(state.DeclaringTypeName, state.MethodName);

            IteratorTypeInfo ti = GetIteratorTypeInfo(iteratorType);
            if (ti == null)
                throw new ArgumentOutOfRangeException(nameof(state), "not an iterator state machine type");

            var iterator = (IEnumerator) ti.Constructor.Invoke(new object[] {state.State});
            ti.Current.SetValue(iterator, state.Current);
            ti.This?.SetValue(iterator, state.This);

            foreach (KeyValuePair<string, object> a in state.Arguments)
            {
                FieldInfo info;
                if (!ti.Arguments.TryGetValue(a.Key, out info))
                    continue;
                info.SetValue(iterator, a.Value);
            }

            foreach (KeyValuePair<string, object> v in state.Variables)
            {
                FieldInfo info;
                if (!ti.Variables.TryGetValue(v.Key, out info))
                    continue;
                info.SetValue(iterator, v.Value);
            }

            return iterator;
        }
        /// <summary>
        /// Convert an iterator to an IteratorState.
        /// </summary>
        /// <param name="iterator">The iterator instance.</param>
        /// <returns>An equivalent IteratorState instance that can be serialized.</returns>
        /// <exception cref="ArgumentNullException">iterator is null</exception>
        /// <exception cref="ArgumentOutOfRangeException">iterator is not a compiler-generated iterator state machine.</exception>
        public IteratorState ToState(IEnumerator iterator)
        {
            if (iterator == null)
                throw new ArgumentNullException(nameof(iterator));

            IteratorTypeInfo ti = GetIteratorTypeInfo(iterator.GetType());

            if (ti == null)
                throw new ArgumentOutOfRangeException(nameof(iterator), "not an iterator state machine type");

            var state = new IteratorState
            {
                DeclaringTypeName = NameUtility.GetSimpleAssemblyQualifiedName(ti.Type.DeclaringType),
                MethodName = ti.MethodName,
                State = (int) ti.State.GetValue(iterator),
                Current = ti.Current.GetValue(iterator)
            };

            if (ti.This != null)
                state.This = ti.This.GetValue(iterator);

            foreach (KeyValuePair<string, FieldInfo> a in ti.Arguments)
                state.Arguments.Add(a.Key, a.Value.GetValue(iterator));

            foreach (KeyValuePair<string, FieldInfo> v in ti.Variables)
                state.Variables.Add(v.Key, v.Value.GetValue(iterator));

            return state;
        }
Пример #3
0
        /// <summary>
        /// Convert an IteratorState to an instance of the iterator it represents.
        /// </summary>
        /// <param name="state">An IteratorState instance.</param>
        /// <returns>An equivalent iterator instance.</returns>
        public IEnumerator FromState(IteratorState state)
        {
            if (state == null)
            {
                throw new ArgumentNullException(nameof(state));
            }

            Type iteratorType = GetIteratorTypeChecked(state.DeclaringTypeName, state.MethodName);

            IteratorTypeInfo ti = GetIteratorTypeInfo(iteratorType);

            if (ti == null)
            {
                throw new ArgumentOutOfRangeException(nameof(state), "not an iterator state machine type");
            }

            var iterator = (IEnumerator)ti.Constructor.Invoke(new object[] { state.State });

            ti.Current.SetValue(iterator, state.Current);
            ti.This?.SetValue(iterator, state.This);

            foreach (KeyValuePair <string, object> a in state.Arguments)
            {
                FieldInfo info;
                if (!ti.Arguments.TryGetValue(a.Key, out info))
                {
                    continue;
                }
                info.SetValue(iterator, a.Value);
            }

            foreach (KeyValuePair <string, object> v in state.Variables)
            {
                FieldInfo info;
                if (!ti.Variables.TryGetValue(v.Key, out info))
                {
                    continue;
                }
                info.SetValue(iterator, v.Value);
            }

            return(iterator);
        }
Пример #4
0
        /// <summary>
        /// Convert an iterator to an IteratorState.
        /// </summary>
        /// <param name="iterator">The iterator instance.</param>
        /// <returns>An equivalent IteratorState instance that can be serialized.</returns>
        /// <exception cref="ArgumentNullException">iterator is null</exception>
        /// <exception cref="ArgumentOutOfRangeException">iterator is not a compiler-generated iterator state machine.</exception>
        public IteratorState ToState(IEnumerator iterator)
        {
            if (iterator == null)
            {
                throw new ArgumentNullException(nameof(iterator));
            }

            IteratorTypeInfo ti = GetIteratorTypeInfo(iterator.GetType());

            if (ti == null)
            {
                throw new ArgumentOutOfRangeException(nameof(iterator), "not an iterator state machine type");
            }

            var state = new IteratorState
            {
                DeclaringTypeName = NameUtility.GetSimpleAssemblyQualifiedName(ti.Type.DeclaringType),
                MethodName        = ti.MethodName,
                State             = (int)ti.State.GetValue(iterator),
                Current           = ti.Current.GetValue(iterator)
            };

            if (ti.This != null)
            {
                state.This = ti.This.GetValue(iterator);
            }

            foreach (KeyValuePair <string, FieldInfo> a in ti.Arguments)
            {
                state.Arguments.Add(a.Key, a.Value.GetValue(iterator));
            }

            foreach (KeyValuePair <string, FieldInfo> v in ti.Variables)
            {
                state.Variables.Add(v.Key, v.Value.GetValue(iterator));
            }

            return(state);
        }