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