private void WriteStructCopyMethodBody(TypeDefinition type, ManagedUnrealTypeInfo structInfo, MethodDefinition copyMethod) { VariableDefinition resultVar = new VariableDefinition(type); copyMethod.Body.Variables.Add(resultVar); ILProcessor processor = copyMethod.Body.GetILProcessor(); processor.Emit(OpCodes.Ldarg_0); processor.Emit(OpCodes.Ldobj, type); processor.Emit(OpCodes.Stloc, resultVar); Instruction lastBranchPosition = null; foreach (ManagedUnrealPropertyInfo propertyInfo in structInfo.Properties) { if (propertyInfo.IsCollection) { FieldDefinition propField = null; foreach (FieldDefinition field in type.Fields) { if (field.Name == propertyInfo.Name) { propField = field; break; } } if (propField == null) { continue; } Type collectionType = GetTypeFromTypeDefinition(propField.FieldType.Resolve()); collectionType = ManagedUnrealTypeInfo.MakeGenericTypeWithPropertyArgs(collectionType, propertyInfo); System.Reflection.ConstructorInfo collectionCtor = null; foreach (System.Reflection.ConstructorInfo ctor in collectionType.GetConstructors()) { System.Reflection.ParameterInfo[] ctorParams = ctor.GetParameters(); if (ctorParams.Length == 1) { if (propertyInfo.Type.TypeCode == EPropertyType.Map) { if (ctorParams[0].ParameterType.Name.Contains("IDictionary") || ctorParams[0].ParameterType.Name.Contains("IReadOnlyDictionary")) { collectionCtor = ctor; } } else if (ctorParams[0].ParameterType.Name.Contains("IEnumerable")) { collectionCtor = ctor; } } } if (collectionCtor == null) { continue; } processor.Emit(OpCodes.Ldarg_0); if (lastBranchPosition != null) { // Branch to be inserted with a branch target of the just written instruction processor.InsertAfter(lastBranchPosition, processor.Create(OpCodes.Brfalse, processor.Body.Instructions[processor.Body.Instructions.Count - 1])); lastBranchPosition = null; } processor.Emit(OpCodes.Ldfld, propField); lastBranchPosition = processor.Body.Instructions[processor.Body.Instructions.Count - 1]; processor.Emit(OpCodes.Ldloca, resultVar); processor.Emit(OpCodes.Ldarg_0); processor.Emit(OpCodes.Ldfld, propField); processor.Emit(OpCodes.Newobj, assembly.MainModule.ImportEx(collectionCtor)); processor.Emit(OpCodes.Stfld, propField); } } processor.Emit(OpCodes.Ldloc, resultVar); if (lastBranchPosition != null) { // Branch to be inserted with a branch target of the just written instruction processor.InsertAfter(lastBranchPosition, processor.Create(OpCodes.Brfalse, processor.Body.Instructions[processor.Body.Instructions.Count - 1])); lastBranchPosition = null; } processor.Emit(OpCodes.Ret); FinalizeMethod(copyMethod); }