public static IEnumerable <CodeInstruction> ConvertToOurInstructions(IEnumerable instructions, List <object> originalInstructions, Dictionary <object, Dictionary <string, object> > unassignedValues) { var result = new List <CodeInstruction>(); var newInstructions = instructions.Cast <object>().ToList(); var index = -1; foreach (var op in newInstructions) { index++; var elementTo = new CodeInstruction(OpCodes.Nop, null); Traverse.IterateFields(op, elementTo, (trvFrom, trvDest) => trvDest.SetValue(trvFrom.GetValue())); if (unassignedValues.TryGetValue(op, out var fields)) { var addExceptionInfo = ShouldAddExceptionInfo(op, index, originalInstructions, newInstructions, unassignedValues); var trv = Traverse.Create(elementTo); foreach (var field in fields) { if (addExceptionInfo || field.Key != nameof(CodeInstruction.blocks)) { trv.Field(field.Key).SetValue(field.Value); } } } yield return(elementTo); } }
private static object ConvertBlock(object originalBlock, Type type) { var block = Activator.CreateInstance(type); Traverse.IterateFields(originalBlock, block, (trvFrom, trvDest) => trvDest.SetValue(trvFrom.GetValue())); return(block); }
public static IEnumerable ConvertInstructions(Type type, IEnumerable enumerable) { var enumerableAssembly = type.GetGenericTypeDefinition().Assembly; var genericListType = enumerableAssembly.GetType(typeof(List <>).FullName); var elementType = type.GetGenericArguments()[0]; var listType = enumerableAssembly.GetType(genericListType.MakeGenericType(new Type[] { elementType }).FullName); var list = Activator.CreateInstance(listType); var listAdd = list.GetType().GetMethod("Add"); foreach (var op in enumerable) { var elementTo = Activator.CreateInstance(elementType, new object[] { OpCodes.Nop, null }); Traverse.IterateFields(op, elementTo, (trvFrom, trvDest) => trvDest.SetValue(trvFrom.GetValue())); listAdd.Invoke(list, new object[] { elementTo }); } return(list as IEnumerable); }
/// <summary>Makes a deep copy of any object</summary> /// <param name="source">The original object</param> /// <param name="resultType">The type of the instance that should be created</param> /// <param name="processor">Optional value transformation function (taking a field name and src/dst traverse objects)</param> /// <param name="pathRoot">The optional path root to start with</param> /// <returns>The copy of the original object</returns> /// public static object MakeDeepCopy(object source, Type resultType, Func <string, Traverse, Traverse, object> processor = null, string pathRoot = "") { if (source == null) { return(null); } var type = source.GetType(); if (type.IsPrimitive) { return(source); } if (type.IsEnum) { return(Enum.ToObject(resultType, (int)source)); } if (type.IsGenericType && resultType.IsGenericType) { var addOperation = FirstMethod(resultType, m => m.Name == "Add" && m.GetParameters().Count() == 1); if (addOperation != null) { var addableResult = Activator.CreateInstance(resultType); var addInvoker = MethodInvoker.GetHandler(addOperation); var newElementType = resultType.GetGenericArguments()[0]; var i = 0; foreach (var element in source as IEnumerable) { var iStr = (i++).ToString(); var path = pathRoot.Length > 0 ? pathRoot + "." + iStr : iStr; var newElement = MakeDeepCopy(element, newElementType, processor, path); addInvoker(addableResult, new object[] { newElement }); } return(addableResult); } // TODO: add dictionaries support // maybe use methods in Dictionary<KeyValuePair<TKey,TVal>> } if (type.IsArray && resultType.IsArray) { var elementType = resultType.GetElementType(); var length = ((Array)source).Length; var arrayResult = Activator.CreateInstance(resultType, new object[] { length }) as object[]; var originalArray = source as object[]; for (var i = 0; i < length; i++) { var iStr = i.ToString(); var path = pathRoot.Length > 0 ? pathRoot + "." + iStr : iStr; arrayResult[i] = MakeDeepCopy(originalArray[i], elementType, processor, path); } return(arrayResult); } var ns = type.Namespace; if (ns == "System" || (ns?.StartsWith("System.") ?? false)) { return(source); } var result = CreateInstance(resultType); Traverse.IterateFields(source, result, (name, src, dst) => { var path = pathRoot.Length > 0 ? pathRoot + "." + name : name; var value = processor != null ? processor(path, src, dst) : src.GetValue(); dst.SetValue(MakeDeepCopy(value, dst.GetValueType(), processor, path)); }); return(result); }