Extension for dynamic/ExpandoObject
Hi, thanks a lot for creating and sharing this library!
I found this cloning library after running into some threading issues while using the DeepCloner nuget package. After digging a while through the DeepCloner code, I decided it would be easier to move on to a different helper class.
After running some tests, I found this helper library for cloning objects.
One thing which I would like to know: Is this library still actively maintained?
I went a little bit through the source code, and also the tests. I had the impression that the unit tests could be extended with some scenarios - I have my own unit test that are testing the basic functionality of the Cloner class. If there is an interest, I could share these tests (or create a PR for them)
Nevertheless, I wanted to share some feedback here: One thing I noticed is the "missing" (or perhaps intentional left out) support for dynamic objects (in my case, I always have an ExpandoObject). Also, if the object already implements ICloneable, it would be good to use the existing Clone() method instead.
Just wanted to share my "workaround" to support this two features, in case anyone is interested:
public static T Clone<T>(T row) {
Type rowType = row.GetType();
//Support for ICloneable
if (typeof(ICloneable).IsAssignableFrom(rowType) && !rowType.IsArray) {
return (T)((ICloneable)row).Clone();
}
//FastDeepCloner does not support dynamic/ExpandoObject, so we need to handle it separately
else if (typeof(IDynamicMetaObjectProvider).IsAssignableFrom(rowType)) {
var ex = row as ExpandoObject;
return (T)DeepCopy(ex);
} else {
var result = FastDeepCloner.DeepCloner.Clone(row);
return (T)result;
}
}
static object DeepCopy<T>(T original) {
var clone = new ExpandoObject();
var _original = (IDictionary<string, object>)original;
var _clone = (IDictionary<string, object>)clone;
foreach (var kvp in _original) {
var valueType = kvp.Value.GetType();
if (valueType.IsPrimitive || valueType == typeof(string)) {
_clone.Add(kvp.Key, kvp.Value);
continue;
}
else if (kvp.Value is ExpandoObject) {
_clone.Add(kvp.Key, DeepCopy((ExpandoObject)kvp.Value));
}
else {
_clone.Add(kvp.Key, kvp.Value.Clone());
}
}
return clone;
}
I've added support for dynamic/ExpandoObject and test coverage into FastCloner which has a similar API. It requires no manual configuration and works out of the box.