I'm have been working on a project to create PDF forms using PDFView4Net. While the library is generally good, the forms creator is primitive and lacking basic features (such as copy/paste, alignment, formatting, etc.) when working with form fields (i.e. text boxes, check boxes, etc.).
The problem: I have been extending the functionality for field objects and getting tripped up on copy/paste. To do this, I need a deep copy of the object with no references to the original whatsoever. I emailed the vendor, requesting information about their recommended method for copying these objects, to which they replied I needed make a copy of each property by hand, manually ... beats head on desk. These are large classes, with multiple embedded classes as properties, as well as UI elements.
The question: Are there any good methods out there that perform a deep copy for complex objects that don't require serialization, doesn't require access to or changes to the source classes and doesn't require a default constructor?
What I have tried/reviewed: I have researched various ways to make a deep copy of an object and discarded them one by one:
- Manually, Property by Painstaking Property: I attempted this with the first of 7 field objects (PDFTextBoxField), but it quickly got out of hand with the multitude properties that are also different types of classes. In the end, I still had lingering references to the original object where it a shallow copy was created instead of a deep copy as intended.
- Serialization: The classes are not marked as Serializable, nor will the vendor change this. I asked them to and they said no.
- ICloneable: Would need to be implemented by the vendor.
- AutoMapper: This seems to be for copying data from one or more object types into another object type. The objects I'm working with are the same type. Though I'm not opposed to using this if it is the best solution.
- Emit Mapper: This project appears to have been abandoned.
- MemberwiseClone: Does a shallow copy, not the deep copy I'm looking for, though this is suggested on a ton of other posts when the questioner specifically requests a deep copy.
- Value Injecter: I implemented FastDeepCloneInjection from ValueInjecter on CodePlex but the majority of the classes that need to be injected from do not have a 0 parameter constructor which is required when creating a new instance for the copy. ValueInjecter doesn't allow skipping of certain properties, or I would just skip the items with no default constructor and leave them set to null (the default). I ran into this right away with the very first class. To attempt to get around the issue, I created a wrapper class inherited from the original and cast the original into the wrapper (and vice versa on return), but I don't think that's a good solution.
Edit: I really do not feel this question is a duplicate. I've searched extensively for a solution, including the post marked as the duplicate/original, and was unable to find a satisfactory resolution. As stated, I don't have access to change the classes that I need to copy. This discounts DataContractSerializer, BinaryFormatter, and any other type of serialization. This also discounts the reflection examples I've seen using Activator.CreateInstance, as about 95% of the classes I need to copy don't have a constructor that takes 0 arguments. This is the same issue I ran into using ValueInjecter. This also discounts using ICloneable.
FormatterServices.GetUninitializedObject(type)
. – Keyes