예제 #1
0

        
예제 #2
0
        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);
            }
        }
예제 #3
0
        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);
        }
예제 #4
0
        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);
        }
예제 #5
0

        
예제 #6
0
        /// <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);
        }