burtsev-alexey / net-object-deep-copy Goto Github PK
View Code? Open in Web Editor NEWC# extension method for fast object cloning.
C# extension method for fast object cloning.
Hi,
shouldn't enum types also return true in the IsPrimitive method?
BR,
Matjaž
Getting compile error in following line:
clonedArray.ForEach((array, indices) => array.SetValue(InternalCopy(clonedArray.GetValue(indices), visited), indices));
For some reason Type is not being recognized anymore even when using UnderlyingSystemType. Please see the following code:
class A {
public A() {Type = typeof(string); }
public Type Type { get; }
}
class Program {
static void Main(string[] args) {
A a1 = new A();
A a2 = ObjectExtensions.Copy(a1);
Console.WriteLine(String.Format("a1.Type {0} typeof(string)", (a1.Type == typeof(string)) ? "==" : "!="));
Console.WriteLine(String.Format("a2.Type {0} typeof(string)", (a2.Type == typeof(string)) ? "==" : "!="));
}
}
Why do I get different results from the clones object vs. the original object?
Hi Alexey,
At first thank you a lot for your job!
I am using your object copy extension in my project and finally found one issue about copying properties of type Expression.
On the picture in the line above the one with exception you can see what I found acceptable for me to fix the issue. Sure you will update ObjectExtensions in the best way.
Kind regards,
Evgenia.
Is it possible to add CopyIgnore Attribute support? Like XmlIgnore or JsonIgnore.
Because i keep getting "An unhandled exception of type 'System.StackOverflowException' occurred in mscorlib.dll" error in this line:
var cloneObject = CloneMethod.Invoke(originalObject, null);
And i can't figure out which object causing this error. If i have CopyIgnore i can one by one add this to fields and figure out which object causing this error.
Edit: I think copying event causing this problem. So if i have CopyIgnore attribute i can use it on event to solve it.
can't copy PropertyInfo, it will 'System.StackOverflowException'
There is probably a better way of doing this but I changed the code to the following to cope with 2 and 3 dimensional arrays:
Array clonedArray = (Array)clonedFieldValue;
if (clonedArray.Rank == 1)
{
for (long i = 0; i < clonedArray.LongLength; i++)
clonedArray.SetValue(InternalCopy(clonedArray.GetValue(i), visited), i);
}
else if (clonedArray.Rank == 2)
{
for (long i = 0; i < clonedArray.GetLongLength(0); i++)
{
for (long j = 0; j < clonedArray.GetLongLength(1); j++)
{
clonedArray.SetValue(InternalCopy(clonedArray.GetValue(i, j), visited), i, j);
}
}
}
else if (clonedArray.Rank == 3)
{
for (long i = 0; i < clonedArray.GetLongLength(0); i++)
{
for (long j = 0; j < clonedArray.GetLongLength(1); j++)
{
for (long k = 0; k < clonedArray.GetLongLength(2); k++)
{
clonedArray.SetValue(InternalCopy(clonedArray.GetValue(i, j, k), visited), i, j, k);
}
}
}
}
else
{
throw new Exception(string.Format("Array has too many dimensions ({0})", clonedArray.Rank));
}
Otherwise, you can construct an array that cannot be copied, like this:
object[] test = new object[1];
test[0] = test;
test.Copy(); // CRASH
Seems to have issues with type PropertyInfo. Is there any way to mark properties of this type as excluded or allowed to reference?
using System;
using System.Collections.Generic;
public class Class1
{
public static void Main(string[] args)
{
Dictionary<Class1, Class1> state1 = new Dictionary<Class1, Class1>();
state1.Add(new Class1(), new Class1());
foreach (Class1 key in state1.Keys)
Console.Write(state1[key]);
Dictionary<Class1, Class1> state2 = state1.Copy();
foreach (Class1 key in state2.Keys)
Console.Write(state2[key]);//Exception
}
}
Occurs for all Dictionarys who use classes as key that do not override GetHashCode()
Alexey, you have a few opened issues and pull requests( some of them possibly address the issues).
Could you please spend some time to clean up the log. Alternatively please specify in readme, that the repository is not maintained any more and provide an option either use other fork(e.g. from pull request https://github.com/chivandikwa/net-object-deep-copy) or suggest someone to become a maintainer of this repository. It is still useful.
Alternatively, refer in Readme.md to some other project, that address the Clone , e.g. https://www.codeproject.com/Articles/1111658/Fast-Deep-Copy-of-Objects-by-Expression-Trees-Csha
Spasibo.
Hi,
The type I was copying looked innocuous enough being a POCO with an IEnumerable property. However these were part of an EF DbContext and at run time that property is lazy loaded so its a DbQuery - that means one massive object graph when recursively including all the private fields. I added some simple debug output to the InternalCopy method so you can see where its going - traversing into other entity types within the same DbContext, etc, etc.
(Note the number after the colon is the 'depth' of the object graph):
MyEntity:1
System.Data.Entity.Infrastructure.DbQuery`1[MyOtherEntityA]:2
System.Data.Entity.Internal.Linq.InternalQuery`1[MyOtherEntityA]:3
System.Data.Entity.Internal.LazyInternalContext:4
System.Data.Entity.Internal.LazyInternalConnection:5
System.Data.Entity.Infrastructure.DbConnectionStringOrigin:6
System.Boolean:6
System.Data.Entity.Infrastructure.Interception.DbInterceptionContext:6
System.Collections.Generic.List`1[System.Data.Entity.DbContext]:7
System.Data.Entity.DbContext[]:8
MyDataContext:9
System.Data.Entity.DbSet`1[MyOtherEntityB]:10
System.Data.Entity.Internal.Linq.InternalSet`1[MyOtherEntityB]:11
System.Data.Entity.Internal.LazyInternalContext:12
System.Data.Entity.Internal.Linq.InternalSet`1[MyOtherEntityB]:11
System.Data.Entity.DbSet`1[MyOtherEntityC]:10
System.Data.Entity.Internal.Linq.InternalSet`1[MyOtherEntityC]:11
System.Data.Entity.Internal.LazyInternalContext:12
System.Data.Entity.Internal.Linq.InternalSet`1[MyOtherEntityC]:11
System.Data.Entity.DbSet`1[MyOtherEntityE]:10
System.Data.Entity.Internal.Linq.InternalSet`1[MyOtherEntityE]:11
System.Data.Entity.Internal.LazyInternalContext:12
I have more output if its useful, I had a guard in there to stop when reaching a depth of 50, otherwise it goes on until the stack overflows.
I realize this maybe a similar outcome to the other stackoverflow issue open on here already, but at least people will note that there are a few different situations this could happen at runtime, without being able to necessarily predict it from the type as written in code.
Hey there,
i've got a class with three custom Enum types, some bools and some strings.
Systemwise i'm using the ms-class System.ServiceProcess.ServiceController and System.Windows.Controls.DatePicker.
last but not least i implement the INotifyPropertyChanged Interface.
public event PropertyChangedEventHandler PropertyChanged;
and:
private void NotifyPropertyChanged(String propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
The error is a stack overflow @ line 28:
var cloneObject = CloneMethod.Invoke(originalObject, null);
Error:
System.StackOverflowException was unhandled
HResult=-2147023895
Message=Eine Ausnahme vom Typ "System.StackOverflowException" wurde ausgelöst.
InnerException:
Edit: Nevermind, my namespace was wrong.
In InternalCopy, there is a line:
CopyFields(originalObject, visited, cloneObject, typeToReflect);
...but then in CopyFields, you have the line:
var clonedFieldValue = InternalCopy(originalFieldValue, visited);
This results in a StackOverflow exception.
I have an object (mostly filled with primitives). It is not possible to clone such an object
The following code returnes the same object.
I would expect that I get always a new object.
var ob = (object)(int)5;
var ob2 = Clone(ob);
var ar = new object[] {new Object(), new Object()};
var cloned = ar.Clone();
Assert.IsFalse(ReferenceEquals(ar[0], cloned[0])); FAIL !!!
Though code works if array is not a root of object graph (when it's a member).
Greetings All,
I took the latest code but I get this compile time error. Does anyone know why we are getting this issue? I appreciate your help.
Getting compile error in following line:
clonedArray.ForEach((array, indices) => array.SetValue(InternalCopy(clonedArray.GetValue(indices), visited), indices));
hi, have you ever try to copy a List object? when I try it on Unity's c# script, it failed. When I debug the code, I found that the array's copy pass the case when the element type is Primitive.
var arrayType = typeToReflect.GetElementType();
if (IsPrimitive(arrayType) == false)
{
Array clonedArray = (Array)cloneObject;
clonedArray.ForEach((array, indices) => array.SetValue(InternalCopy(clonedArray.GetValue(indices), visited), indices));
}
But this cause the primitive element array would not get the memory allocated, after I add code
else
{
Array oArr = (Array)originalObject;
Array clonedArray = Array.CreateInstance(arrayType, oArr.Length);
Array.Copy(oArr, clonedArray, oArr.Length);
cloneObject = clonedArray;
}
it fixed.
Hi,
I recently saw a link to your cloning methods from stackoverflow and decided to try them out. I had my own methods that used a similar method, but I was creating my deep clone instances using Activator instead of MemberwiseClone, and your way has less side effects. However, I noticed that it only clones the private fields of the original object type and not fields of the objects base type(s) (if any).
The following change will take care of that:
Type reflectingType = originalType
while (reflectingType != null)
{
foreach (.....
{
// nothing changed here
}
reflectingType = reflectingType.BaseType
}
Again, great work on this deep-clone, love it.
Tim
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.