Repository files navigation

DeepCloner

Library with extenstion to clone objects for .NET. It can deep or shallow copy objects. In deep cloning all object graph is maintained. Library actively uses code-generation in runtime as result object cloning is blazingly fast. Also, there are some performance tricks to increase cloning speed (see tests below). Objects are copied by its' internal structure, no methods or constructuctors are called for cloning objects. As result, you can copy any object, but we don't recommend to copy objects which are binded to native resources or pointers. It can cause unpredictable results (but object will be cloned).

You don't need to mark objects somehow, like Serializable-attribute, or restrict to specific interface. Absolutely any object can be cloned by this library. And this object doesn't have any ability to determine that he is clone (except with very specific methods).

Also, there is no requirement to specify object type for cloning. Object can be casted to inteface or as an abstract object, you can clone array of ints as abstract Array or IEnumerable, even null can be cloned without any errors.

Installation through Nuget:

	Install-Package DeepCloner

Supported Frameworks

DeepCloner works for .NET 4.0 or higher or for .NET Standard 1.3 (.NET Core). .NET Standard version implements only Safe copying variant (slightly slower than standard, see Benchmarks).

Limitation

Library requires Full Trust permission set or Reflection permission (MemberAccess). It prefers Full Trust, but if code lacks of this variant, library seamlessly switchs to slighlty slower but safer variant.

If your code is on very limited permission set, you can try to use another library, e.g. CloneExtensions. It clones only public properties of objects, so, result can differ, but should work better (it requires only RestrictedMemberAccess permission).

Usage

Deep cloning any object:

 var clone = new { Id = 1, Name = "222" }.DeepClone();

With a reference to same object:

 // public class Tree { public Tree ParentTree; }
var t = new Tree();
t.ParentTree = t;
var cloned = t.DeepClone();
Console.WriteLine(cloned.ParentTree == cloned); // True

Or as object:

 var date = DateTime.Now;
var obj = (object)date;
obj.DeepClone().GetType(); // DateTime

Shallow cloning (clone only same object, not objects that object relate to)

 var clone = new { Id = 1, Name = "222" }.ShallowClone();

Cloning to existing object (can be useful for copying constructors, creating wrappers or for keeping references to same object)

public class Derived : BaseClass
{
public Derived(BaseClass parent)
{
parent.DeepCloneTo(this); // now this has every field from parent
}
}

Please, note, that DeepCloneTo and ShallowCloneTo requre that object should be class (it is useless for structures) and derived class must be real descendant of parent class (or same type). In another words, this code will not work:

public class Base {}
public class Derived1 : Base {}
public class Derived2 : Base {}
var b = (Base)new Derived1(); // casting derived to parent
var derived2 = new Derived2();
// will compile, but will throw an exception in runtime, Derived1 is not parent for Derived2
b.DeepCloneTo(derived2); 

Installation

Through nuget:

 Install-Package DeepCloner

Details

You can use deep clone of objects for a lot of situations, e.g.:

  • Emulation of external service or deserialization elimination (e.g. in Unit Testing). When code has received object from external source, code can change it (because object for code is own).
  • ReadOnly object replace. Instead of wrapping your object to readonly object, you can clone object and target code can do anything with it without any restriction.
  • Caching. You can cache data locally and want to ensurce that cached object hadn't been changed by other code

You can use shallow clone as fast, light version of deep clone (if your situation allows that). Main difference between deep and shallow clone in code below:

 // public class A { public B B; }
// public class B { public int X; }
var b = new B { X = 1 };
var a = new A { B = b };
var deepClone = a.DeepClone();
deepClone.B.X = 2;
Console.WriteLine(a.B.X); // 1
var shallowClone = a.ShallowClone();
shallowClone.B.X = 2;
Console.WriteLine(a.B.X); // 2

So, deep cloning is guarantee that all changes of cloned object does not affect original. Shallow clone does not guarantee this. But it faster, because deep clone of object can copy big graph of related objects and related objects of related objects and related related related objects, and... so on...

This library does not call any method of cloning object: constructors, Equals, GetHashCode, propertes - nothing is called. So, it is impossible for cloning object to receive information about cloning, throw an exception or return invalid data. If you need to call some methods after cloning, you can wrap cloning call to another method which will perform required actions.

Extension methods in library are generic, but it is not require to specifify type for cloning. You can cast your objects to System.Object, or to an interface, add fields will be carefully copied to new object.

Performance

Cloning Speed can vary on many factors. This library contains some optimizations, e.g. structs are just copied, arrays also can be copied through Array.Copy if possible. So, real performance will depend on structure of your object.

Tables below, just for information. Simple object with some fields is cloned multiple times. Preparation time (only affect first execution) excluded from tests.

Example of object

var c = new C1 { V1 = 1, O = new object(), V2 = "xxx" };
var c1 = new C1Complex { C1 = c, Guid = Guid.NewGuid(), O = new object(), V1 = 42, V2 = "some test string", Array = new[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 } };

Deep cloning

MethodTime per object (ns)Comments
Manual50You should manually realize cloning. It requires a lot of work and can cause copy-paste errors, but it is fastest variant
DeepClone / Unsafe570This variant is really slower than manual, but clones any object without preparation
DeepClone / Safe760Safe variant based on on expressions
CloneExtensions1800Implementation of cloning objects on expression trees.
NClone2890Not analyzed carefully, but author says that lib has a problem with a cyclic dependencies
Clone.Behave!41890Very slow, also has a dependency to fasterflect
GeorgeCloney6420Has a lot limitations and prefers to clone through BinaryFormatter
Nuclex.Cloningn/aCrashed with a null reference exception
.Net Object FastDeepCloner15030Not analyzed carefully, only for .NET 4.5.1 or higher
DesertOctopus1700Not analyzed. Only for .NET 4.5.2 or higher
BinaryFormatter49100Another way of deep object cloning through serializing/deserializing object. Instead of Json serializers - it maintains full graph of serializing objects and also do not call any method for cloning object. But due serious overhead, this variant is very slow

Shallow cloning Shallow cloning is usually faster, because we no need to calculate references and clone additional objects.

MethodTime per object (ns)Comments
Manual16You should manually realize clone, property by property, field by field. Fastest variant
Manual / MemberwiseClone46Fast variant to clone: call MemberwiseClone inside your class. Should be done manually, but does not require a lot of work.
ShallowClone / Unsafe64Slightly slower than MemberwiseClone due checks for nulls and object types
ShallowClone / Safe64Safe variant based on expressions
CloneExtensions125Implementation of cloning objects on expression trees.
Nuclex.Cloning2498Looks like interesting expression-based implementation with a some caching, but unexpectedly very slow

Performance tricks

We perform a lot of performance tricks to ensure cloning is really fast. Here is some of them:

  • Using a shallow cloning instead of deep cloning if object is safe for this operation
  • Copying an whole object and updating only required fields
  • Special handling for structs (can be copied without any cloning code, if possible)
  • Cloners caching
  • Optimizations for copying simple objects (reduced number of checks to ensure good performance)
  • Special handling of reference count for simple objects, that is faster than default dictionary
  • Constructors analyzing to select best variant of object construction
  • Direct copying of arrays if possible
  • Custom handling of one-dimensional and two-dimensional zero-based arrays (most of arrays in usual code)

License

MIT license

About

Fast object cloner for .NET

Resources

Stars

575 stars

Watchers

13 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Repository files navigation

DeepCloner

Library with extenstion to clone objects for .NET. It can deep or shallow copy objects. In deep cloning all object graph is maintained. Library actively uses code-generation in runtime as result object cloning is blazingly fast. Also, there are some performance tricks to increase cloning speed (see tests below). Objects are copied by its' internal structure, no methods or constructuctors are called for cloning objects. As result, you can copy any object, but we don't recommend to copy objects which are binded to native resources or pointers. It can cause unpredictable results (but object will be cloned).

You don't need to mark objects somehow, like Serializable-attribute, or restrict to specific interface. Absolutely any object can be cloned by this library. And this object doesn't have any ability to determine that he is clone (except with very specific methods).

Also, there is no requirement to specify object type for cloning. Object can be casted to inteface or as an abstract object, you can clone array of ints as abstract Array or IEnumerable, even null can be cloned without any errors.

Installation through Nuget:

	Install-Package DeepCloner

Supported Frameworks

DeepCloner works for .NET 4.0 or higher or for .NET Standard 1.3 (.NET Core). .NET Standard version implements only Safe copying variant (slightly slower than standard, see Benchmarks).

Limitation

Library requires Full Trust permission set or Reflection permission (MemberAccess). It prefers Full Trust, but if code lacks of this variant, library seamlessly switchs to slighlty slower but safer variant.

If your code is on very limited permission set, you can try to use another library, e.g. CloneExtensions. It clones only public properties of objects, so, result can differ, but should work better (it requires only RestrictedMemberAccess permission).

Usage

Deep cloning any object:

 var clone = new { Id = 1, Name = "222" }.DeepClone();

With a reference to same object:

 // public class Tree { public Tree ParentTree; }
var t = new Tree();
t.ParentTree = t;
var cloned = t.DeepClone();
Console.WriteLine(cloned.ParentTree == cloned); // True

Or as object:

 var date = DateTime.Now;
var obj = (object)date;
obj.DeepClone().GetType(); // DateTime

Shallow cloning (clone only same object, not objects that object relate to)

 var clone = new { Id = 1, Name = "222" }.ShallowClone();

Cloning to existing object (can be useful for copying constructors, creating wrappers or for keeping references to same object)

public class Derived : BaseClass
{
public Derived(BaseClass parent)
{
parent.DeepCloneTo(this); // now this has every field from parent
}
}

Please, note, that DeepCloneTo and ShallowCloneTo requre that object should be class (it is useless for structures) and derived class must be real descendant of parent class (or same type). In another words, this code will not work:

public class Base {}
public class Derived1 : Base {}
public class Derived2 : Base {}
var b = (Base)new Derived1(); // casting derived to parent
var derived2 = new Derived2();
// will compile, but will throw an exception in runtime, Derived1 is not parent for Derived2
b.DeepCloneTo(derived2); 

Installation

Through nuget:

 Install-Package DeepCloner

Details

You can use deep clone of objects for a lot of situations, e.g.:

  • Emulation of external service or deserialization elimination (e.g. in Unit Testing). When code has received object from external source, code can change it (because object for code is own).
  • ReadOnly object replace. Instead of wrapping your object to readonly object, you can clone object and target code can do anything with it without any restriction.
  • Caching. You can cache data locally and want to ensurce that cached object hadn't been changed by other code

You can use shallow clone as fast, light version of deep clone (if your situation allows that). Main difference between deep and shallow clone in code below:

 // public class A { public B B; }
// public class B { public int X; }
var b = new B { X = 1 };
var a = new A { B = b };
var deepClone = a.DeepClone();
deepClone.B.X = 2;
Console.WriteLine(a.B.X); // 1
var shallowClone = a.ShallowClone();
shallowClone.B.X = 2;
Console.WriteLine(a.B.X); // 2

So, deep cloning is guarantee that all changes of cloned object does not affect original. Shallow clone does not guarantee this. But it faster, because deep clone of object can copy big graph of related objects and related objects of related objects and related related related objects, and... so on...

This library does not call any method of cloning object: constructors, Equals, GetHashCode, propertes - nothing is called. So, it is impossible for cloning object to receive information about cloning, throw an exception or return invalid data. If you need to call some methods after cloning, you can wrap cloning call to another method which will perform required actions.

Extension methods in library are generic, but it is not require to specifify type for cloning. You can cast your objects to System.Object, or to an interface, add fields will be carefully copied to new object.

Performance

Cloning Speed can vary on many factors. This library contains some optimizations, e.g. structs are just copied, arrays also can be copied through Array.Copy if possible. So, real performance will depend on structure of your object.

Tables below, just for information. Simple object with some fields is cloned multiple times. Preparation time (only affect first execution) excluded from tests.

Example of object

var c = new C1 { V1 = 1, O = new object(), V2 = "xxx" };
var c1 = new C1Complex { C1 = c, Guid = Guid.NewGuid(), O = new object(), V1 = 42, V2 = "some test string", Array = new[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 } };

Deep cloning

MethodTime per object (ns)Comments
Manual50You should manually realize cloning. It requires a lot of work and can cause copy-paste errors, but it is fastest variant
DeepClone / Unsafe570This variant is really slower than manual, but clones any object without preparation
DeepClone / Safe760Safe variant based on on expressions
CloneExtensions1800Implementation of cloning objects on expression trees.
NClone2890Not analyzed carefully, but author says that lib has a problem with a cyclic dependencies
Clone.Behave!41890Very slow, also has a dependency to fasterflect
GeorgeCloney6420Has a lot limitations and prefers to clone through BinaryFormatter
Nuclex.Cloningn/aCrashed with a null reference exception
.Net Object FastDeepCloner15030Not analyzed carefully, only for .NET 4.5.1 or higher
DesertOctopus1700Not analyzed. Only for .NET 4.5.2 or higher
BinaryFormatter49100Another way of deep object cloning through serializing/deserializing object. Instead of Json serializers - it maintains full graph of serializing objects and also do not call any method for cloning object. But due serious overhead, this variant is very slow

Shallow cloning Shallow cloning is usually faster, because we no need to calculate references and clone additional objects.

MethodTime per object (ns)Comments
Manual16You should manually realize clone, property by property, field by field. Fastest variant
Manual / MemberwiseClone46Fast variant to clone: call MemberwiseClone inside your class. Should be done manually, but does not require a lot of work.
ShallowClone / Unsafe64Slightly slower than MemberwiseClone due checks for nulls and object types
ShallowClone / Safe64Safe variant based on expressions
CloneExtensions125Implementation of cloning objects on expression trees.
Nuclex.Cloning2498Looks like interesting expression-based implementation with a some caching, but unexpectedly very slow

Performance tricks

We perform a lot of performance tricks to ensure cloning is really fast. Here is some of them:

  • Using a shallow cloning instead of deep cloning if object is safe for this operation
  • Copying an whole object and updating only required fields
  • Special handling for structs (can be copied without any cloning code, if possible)
  • Cloners caching
  • Optimizations for copying simple objects (reduced number of checks to ensure good performance)
  • Special handling of reference count for simple objects, that is faster than default dictionary
  • Constructors analyzing to select best variant of object construction
  • Direct copying of arrays if possible
  • Custom handling of one-dimensional and two-dimensional zero-based arrays (most of arrays in usual code)

License

MIT license

About

Fast object cloner for .NET

Resources

Stars

575 stars

Watchers

13 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

DeepCloner

Library with extenstion to clone objects for .NET. It can deep or shallow copy objects. In deep cloning all object graph is maintained. Library actively uses code-generation in runtime as result object cloning is blazingly fast. Also, there are some performance tricks to increase cloning speed (see tests below). Objects are copied by its' internal structure, no methods or constructuctors are called for cloning objects. As result, you can copy any object, but we don't recommend to copy objects which are binded to native resources or pointers. It can cause unpredictable results (but object will be cloned).

You don't need to mark objects somehow, like Serializable-attribute, or restrict to specific interface. Absolutely any object can be cloned by this library. And this object doesn't have any ability to determine that he is clone (except with very specific methods).

Also, there is no requirement to specify object type for cloning. Object can be casted to inteface or as an abstract object, you can clone array of ints as abstract Array or IEnumerable, even null can be cloned without any errors.

Installation through Nuget:

	Install-Package DeepCloner

Supported Frameworks

DeepCloner works for .NET 4.0 or higher or for .NET Standard 1.3 (.NET Core). .NET Standard version implements only Safe copying variant (slightly slower than standard, see Benchmarks).

Limitation

Library requires Full Trust permission set or Reflection permission (MemberAccess). It prefers Full Trust, but if code lacks of this variant, library seamlessly switchs to slighlty slower but safer variant.

If your code is on very limited permission set, you can try to use another library, e.g. CloneExtensions. It clones only public properties of objects, so, result can differ, but should work better (it requires only RestrictedMemberAccess permission).

Usage

Deep cloning any object:

 var clone = new { Id = 1, Name = "222" }.DeepClone();

With a reference to same object:

 // public class Tree { public Tree ParentTree; }
var t = new Tree();
t.ParentTree = t;
var cloned = t.DeepClone();
Console.WriteLine(cloned.ParentTree == cloned); // True

Or as object:

 var date = DateTime.Now;
var obj = (object)date;
obj.DeepClone().GetType(); // DateTime

Shallow cloning (clone only same object, not objects that object relate to)

 var clone = new { Id = 1, Name = "222" }.ShallowClone();

Cloning to existing object (can be useful for copying constructors, creating wrappers or for keeping references to same object)

public class Derived : BaseClass
{
public Derived(BaseClass parent)
{
parent.DeepCloneTo(this); // now this has every field from parent
}
}

Please, note, that DeepCloneTo and ShallowCloneTo requre that object should be class (it is useless for structures) and derived class must be real descendant of parent class (or same type). In another words, this code will not work:

public class Base {}
public class Derived1 : Base {}
public class Derived2 : Base {}
var b = (Base)new Derived1(); // casting derived to parent
var derived2 = new Derived2();
// will compile, but will throw an exception in runtime, Derived1 is not parent for Derived2
b.DeepCloneTo(derived2); 

Installation

Through nuget:

 Install-Package DeepCloner

Details

You can use deep clone of objects for a lot of situations, e.g.:

  • Emulation of external service or deserialization elimination (e.g. in Unit Testing). When code has received object from external source, code can change it (because object for code is own).
  • ReadOnly object replace. Instead of wrapping your object to readonly object, you can clone object and target code can do anything with it without any restriction.
  • Caching. You can cache data locally and want to ensurce that cached object hadn't been changed by other code

You can use shallow clone as fast, light version of deep clone (if your situation allows that). Main difference between deep and shallow clone in code below:

 // public class A { public B B; }
// public class B { public int X; }
var b = new B { X = 1 };
var a = new A { B = b };
var deepClone = a.DeepClone();
deepClone.B.X = 2;
Console.WriteLine(a.B.X); // 1
var shallowClone = a.ShallowClone();
shallowClone.B.X = 2;
Console.WriteLine(a.B.X); // 2

So, deep cloning is guarantee that all changes of cloned object does not affect original. Shallow clone does not guarantee this. But it faster, because deep clone of object can copy big graph of related objects and related objects of related objects and related related related objects, and... so on...

This library does not call any method of cloning object: constructors, Equals, GetHashCode, propertes - nothing is called. So, it is impossible for cloning object to receive information about cloning, throw an exception or return invalid data. If you need to call some methods after cloning, you can wrap cloning call to another method which will perform required actions.

Extension methods in library are generic, but it is not require to specifify type for cloning. You can cast your objects to System.Object, or to an interface, add fields will be carefully copied to new object.

Performance

Cloning Speed can vary on many factors. This library contains some optimizations, e.g. structs are just copied, arrays also can be copied through Array.Copy if possible. So, real performance will depend on structure of your object.

Tables below, just for information. Simple object with some fields is cloned multiple times. Preparation time (only affect first execution) excluded from tests.

Example of object

var c = new C1 { V1 = 1, O = new object(), V2 = "xxx" };
var c1 = new C1Complex { C1 = c, Guid = Guid.NewGuid(), O = new object(), V1 = 42, V2 = "some test string", Array = new[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 } };

Deep cloning

MethodTime per object (ns)Comments
Manual50You should manually realize cloning. It requires a lot of work and can cause copy-paste errors, but it is fastest variant
DeepClone / Unsafe570This variant is really slower than manual, but clones any object without preparation
DeepClone / Safe760Safe variant based on on expressions
CloneExtensions1800Implementation of cloning objects on expression trees.
NClone2890Not analyzed carefully, but author says that lib has a problem with a cyclic dependencies
Clone.Behave!41890Very slow, also has a dependency to fasterflect
GeorgeCloney6420Has a lot limitations and prefers to clone through BinaryFormatter
Nuclex.Cloningn/aCrashed with a null reference exception
.Net Object FastDeepCloner15030Not analyzed carefully, only for .NET 4.5.1 or higher
DesertOctopus1700Not analyzed. Only for .NET 4.5.2 or higher
BinaryFormatter49100Another way of deep object cloning through serializing/deserializing object. Instead of Json serializers - it maintains full graph of serializing objects and also do not call any method for cloning object. But due serious overhead, this variant is very slow

Shallow cloning Shallow cloning is usually faster, because we no need to calculate references and clone additional objects.

MethodTime per object (ns)Comments
Manual16You should manually realize clone, property by property, field by field. Fastest variant
Manual / MemberwiseClone46Fast variant to clone: call MemberwiseClone inside your class. Should be done manually, but does not require a lot of work.
ShallowClone / Unsafe64Slightly slower than MemberwiseClone due checks for nulls and object types
ShallowClone / Safe64Safe variant based on expressions
CloneExtensions125Implementation of cloning objects on expression trees.
Nuclex.Cloning2498Looks like interesting expression-based implementation with a some caching, but unexpectedly very slow

Performance tricks

We perform a lot of performance tricks to ensure cloning is really fast. Here is some of them:

  • Using a shallow cloning instead of deep cloning if object is safe for this operation
  • Copying an whole object and updating only required fields
  • Special handling for structs (can be copied without any cloning code, if possible)
  • Cloners caching
  • Optimizations for copying simple objects (reduced number of checks to ensure good performance)
  • Special handling of reference count for simple objects, that is faster than default dictionary
  • Constructors analyzing to select best variant of object construction
  • Direct copying of arrays if possible
  • Custom handling of one-dimensional and two-dimensional zero-based arrays (most of arrays in usual code)

License

MIT license

About

Fast object cloner for .NET

Resources

Stars

575 stars

Watchers

13 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

DeepCloner

Library with extenstion to clone objects for .NET. It can deep or shallow copy objects. In deep cloning all object graph is maintained. Library actively uses code-generation in runtime as result object cloning is blazingly fast. Also, there are some performance tricks to increase cloning speed (see tests below). Objects are copied by its' internal structure, no methods or constructuctors are called for cloning objects. As result, you can copy any object, but we don't recommend to copy objects which are binded to native resources or pointers. It can cause unpredictable results (but object will be cloned).

You don't need to mark objects somehow, like Serializable-attribute, or restrict to specific interface. Absolutely any object can be cloned by this library. And this object doesn't have any ability to determine that he is clone (except with very specific methods).

Also, there is no requirement to specify object type for cloning. Object can be casted to inteface or as an abstract object, you can clone array of ints as abstract Array or IEnumerable, even null can be cloned without any errors.

Installation through Nuget:

	Install-Package DeepCloner

Supported Frameworks

DeepCloner works for .NET 4.0 or higher or for .NET Standard 1.3 (.NET Core). .NET Standard version implements only Safe copying variant (slightly slower than standard, see Benchmarks).

Limitation

Library requires Full Trust permission set or Reflection permission (MemberAccess). It prefers Full Trust, but if code lacks of this variant, library seamlessly switchs to slighlty slower but safer variant.

If your code is on very limited permission set, you can try to use another library, e.g. CloneExtensions. It clones only public properties of objects, so, result can differ, but should work better (it requires only RestrictedMemberAccess permission).

Usage

Deep cloning any object:

 var clone = new { Id = 1, Name = "222" }.DeepClone();

With a reference to same object:

 // public class Tree { public Tree ParentTree; }
var t = new Tree();
t.ParentTree = t;
var cloned = t.DeepClone();
Console.WriteLine(cloned.ParentTree == cloned); // True

Or as object:

 var date = DateTime.Now;
var obj = (object)date;
obj.DeepClone().GetType(); // DateTime

Shallow cloning (clone only same object, not objects that object relate to)

 var clone = new { Id = 1, Name = "222" }.ShallowClone();

Cloning to existing object (can be useful for copying constructors, creating wrappers or for keeping references to same object)

public class Derived : BaseClass
{
public Derived(BaseClass parent)
{
parent.DeepCloneTo(this); // now this has every field from parent
}
}

Please, note, that DeepCloneTo and ShallowCloneTo requre that object should be class (it is useless for structures) and derived class must be real descendant of parent class (or same type). In another words, this code will not work:

public class Base {}
public class Derived1 : Base {}
public class Derived2 : Base {}
var b = (Base)new Derived1(); // casting derived to parent
var derived2 = new Derived2();
// will compile, but will throw an exception in runtime, Derived1 is not parent for Derived2
b.DeepCloneTo(derived2); 

Installation

Through nuget:

 Install-Package DeepCloner

Details

You can use deep clone of objects for a lot of situations, e.g.:

  • Emulation of external service or deserialization elimination (e.g. in Unit Testing). When code has received object from external source, code can change it (because object for code is own).
  • ReadOnly object replace. Instead of wrapping your object to readonly object, you can clone object and target code can do anything with it without any restriction.
  • Caching. You can cache data locally and want to ensurce that cached object hadn't been changed by other code

You can use shallow clone as fast, light version of deep clone (if your situation allows that). Main difference between deep and shallow clone in code below:

 // public class A { public B B; }
// public class B { public int X; }
var b = new B { X = 1 };
var a = new A { B = b };
var deepClone = a.DeepClone();
deepClone.B.X = 2;
Console.WriteLine(a.B.X); // 1
var shallowClone = a.ShallowClone();
shallowClone.B.X = 2;
Console.WriteLine(a.B.X); // 2

So, deep cloning is guarantee that all changes of cloned object does not affect original. Shallow clone does not guarantee this. But it faster, because deep clone of object can copy big graph of related objects and related objects of related objects and related related related objects, and... so on...

This library does not call any method of cloning object: constructors, Equals, GetHashCode, propertes - nothing is called. So, it is impossible for cloning object to receive information about cloning, throw an exception or return invalid data. If you need to call some methods after cloning, you can wrap cloning call to another method which will perform required actions.

Extension methods in library are generic, but it is not require to specifify type for cloning. You can cast your objects to System.Object, or to an interface, add fields will be carefully copied to new object.

Performance

Cloning Speed can vary on many factors. This library contains some optimizations, e.g. structs are just copied, arrays also can be copied through Array.Copy if possible. So, real performance will depend on structure of your object.

Tables below, just for information. Simple object with some fields is cloned multiple times. Preparation time (only affect first execution) excluded from tests.

Example of object

var c = new C1 { V1 = 1, O = new object(), V2 = "xxx" };
var c1 = new C1Complex { C1 = c, Guid = Guid.NewGuid(), O = new object(), V1 = 42, V2 = "some test string", Array = new[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 } };

Deep cloning

MethodTime per object (ns)Comments
Manual50You should manually realize cloning. It requires a lot of work and can cause copy-paste errors, but it is fastest variant
DeepClone / Unsafe570This variant is really slower than manual, but clones any object without preparation
DeepClone / Safe760Safe variant based on on expressions
CloneExtensions1800Implementation of cloning objects on expression trees.
NClone2890Not analyzed carefully, but author says that lib has a problem with a cyclic dependencies
Clone.Behave!41890Very slow, also has a dependency to fasterflect
GeorgeCloney6420Has a lot limitations and prefers to clone through BinaryFormatter
Nuclex.Cloningn/aCrashed with a null reference exception
.Net Object FastDeepCloner15030Not analyzed carefully, only for .NET 4.5.1 or higher
DesertOctopus1700Not analyzed. Only for .NET 4.5.2 or higher
BinaryFormatter49100Another way of deep object cloning through serializing/deserializing object. Instead of Json serializers - it maintains full graph of serializing objects and also do not call any method for cloning object. But due serious overhead, this variant is very slow

Shallow cloning Shallow cloning is usually faster, because we no need to calculate references and clone additional objects.

MethodTime per object (ns)Comments
Manual16You should manually realize clone, property by property, field by field. Fastest variant
Manual / MemberwiseClone46Fast variant to clone: call MemberwiseClone inside your class. Should be done manually, but does not require a lot of work.
ShallowClone / Unsafe64Slightly slower than MemberwiseClone due checks for nulls and object types
ShallowClone / Safe64Safe variant based on expressions
CloneExtensions125Implementation of cloning objects on expression trees.
Nuclex.Cloning2498Looks like interesting expression-based implementation with a some caching, but unexpectedly very slow

Performance tricks

We perform a lot of performance tricks to ensure cloning is really fast. Here is some of them:

  • Using a shallow cloning instead of deep cloning if object is safe for this operation
  • Copying an whole object and updating only required fields
  • Special handling for structs (can be copied without any cloning code, if possible)
  • Cloners caching
  • Optimizations for copying simple objects (reduced number of checks to ensure good performance)
  • Special handling of reference count for simple objects, that is faster than default dictionary
  • Constructors analyzing to select best variant of object construction
  • Direct copying of arrays if possible
  • Custom handling of one-dimensional and two-dimensional zero-based arrays (most of arrays in usual code)

License

MIT license

About

Fast object cloner for .NET

Resources

Stars

575 stars

Watchers

13 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Repository files navigation

DeepCloner

Library with extenstion to clone objects for .NET. It can deep or shallow copy objects. In deep cloning all object graph is maintained. Library actively uses code-generation in runtime as result object cloning is blazingly fast. Also, there are some performance tricks to increase cloning speed (see tests below). Objects are copied by its' internal structure, no methods or constructuctors are called for cloning objects. As result, you can copy any object, but we don't recommend to copy objects which are binded to native resources or pointers. It can cause unpredictable results (but object will be cloned).

You don't need to mark objects somehow, like Serializable-attribute, or restrict to specific interface. Absolutely any object can be cloned by this library. And this object doesn't have any ability to determine that he is clone (except with very specific methods).

Also, there is no requirement to specify object type for cloning. Object can be casted to inteface or as an abstract object, you can clone array of ints as abstract Array or IEnumerable, even null can be cloned without any errors.

Installation through Nuget:

	Install-Package DeepCloner

Supported Frameworks

DeepCloner works for .NET 4.0 or higher or for .NET Standard 1.3 (.NET Core). .NET Standard version implements only Safe copying variant (slightly slower than standard, see Benchmarks).

Limitation

Library requires Full Trust permission set or Reflection permission (MemberAccess). It prefers Full Trust, but if code lacks of this variant, library seamlessly switchs to slighlty slower but safer variant.

If your code is on very limited permission set, you can try to use another library, e.g. CloneExtensions. It clones only public properties of objects, so, result can differ, but should work better (it requires only RestrictedMemberAccess permission).

Usage

Deep cloning any object:

 var clone = new { Id = 1, Name = "222" }.DeepClone();

With a reference to same object:

 // public class Tree { public Tree ParentTree; }
var t = new Tree();
t.ParentTree = t;
var cloned = t.DeepClone();
Console.WriteLine(cloned.ParentTree == cloned); // True

Or as object:

 var date = DateTime.Now;
var obj = (object)date;
obj.DeepClone().GetType(); // DateTime

Shallow cloning (clone only same object, not objects that object relate to)

 var clone = new { Id = 1, Name = "222" }.ShallowClone();

Cloning to existing object (can be useful for copying constructors, creating wrappers or for keeping references to same object)

public class Derived : BaseClass
{
public Derived(BaseClass parent)
{
parent.DeepCloneTo(this); // now this has every field from parent
}
}

Please, note, that DeepCloneTo and ShallowCloneTo requre that object should be class (it is useless for structures) and derived class must be real descendant of parent class (or same type). In another words, this code will not work:

public class Base {}
public class Derived1 : Base {}
public class Derived2 : Base {}
var b = (Base)new Derived1(); // casting derived to parent
var derived2 = new Derived2();
// will compile, but will throw an exception in runtime, Derived1 is not parent for Derived2
b.DeepCloneTo(derived2); 

Installation

Through nuget:

 Install-Package DeepCloner

Details

You can use deep clone of objects for a lot of situations, e.g.:

  • Emulation of external service or deserialization elimination (e.g. in Unit Testing). When code has received object from external source, code can change it (because object for code is own).
  • ReadOnly object replace. Instead of wrapping your object to readonly object, you can clone object and target code can do anything with it without any restriction.
  • Caching. You can cache data locally and want to ensurce that cached object hadn't been changed by other code

You can use shallow clone as fast, light version of deep clone (if your situation allows that). Main difference between deep and shallow clone in code below:

 // public class A { public B B; }
// public class B { public int X; }
var b = new B { X = 1 };
var a = new A { B = b };
var deepClone = a.DeepClone();
deepClone.B.X = 2;
Console.WriteLine(a.B.X); // 1
var shallowClone = a.ShallowClone();
shallowClone.B.X = 2;
Console.WriteLine(a.B.X); // 2

So, deep cloning is guarantee that all changes of cloned object does not affect original. Shallow clone does not guarantee this. But it faster, because deep clone of object can copy big graph of related objects and related objects of related objects and related related related objects, and... so on...

This library does not call any method of cloning object: constructors, Equals, GetHashCode, propertes - nothing is called. So, it is impossible for cloning object to receive information about cloning, throw an exception or return invalid data. If you need to call some methods after cloning, you can wrap cloning call to another method which will perform required actions.

Extension methods in library are generic, but it is not require to specifify type for cloning. You can cast your objects to System.Object, or to an interface, add fields will be carefully copied to new object.

Performance

Cloning Speed can vary on many factors. This library contains some optimizations, e.g. structs are just copied, arrays also can be copied through Array.Copy if possible. So, real performance will depend on structure of your object.

Tables below, just for information. Simple object with some fields is cloned multiple times. Preparation time (only affect first execution) excluded from tests.

Example of object

var c = new C1 { V1 = 1, O = new object(), V2 = "xxx" };
var c1 = new C1Complex { C1 = c, Guid = Guid.NewGuid(), O = new object(), V1 = 42, V2 = "some test string", Array = new[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 } };

Deep cloning

MethodTime per object (ns)Comments
Manual50You should manually realize cloning. It requires a lot of work and can cause copy-paste errors, but it is fastest variant
DeepClone / Unsafe570This variant is really slower than manual, but clones any object without preparation
DeepClone / Safe760Safe variant based on on expressions
CloneExtensions1800Implementation of cloning objects on expression trees.
NClone2890Not analyzed carefully, but author says that lib has a problem with a cyclic dependencies
Clone.Behave!41890Very slow, also has a dependency to fasterflect
GeorgeCloney6420Has a lot limitations and prefers to clone through BinaryFormatter
Nuclex.Cloningn/aCrashed with a null reference exception
.Net Object FastDeepCloner15030Not analyzed carefully, only for .NET 4.5.1 or higher
DesertOctopus1700Not analyzed. Only for .NET 4.5.2 or higher
BinaryFormatter49100Another way of deep object cloning through serializing/deserializing object. Instead of Json serializers - it maintains full graph of serializing objects and also do not call any method for cloning object. But due serious overhead, this variant is very slow

Shallow cloning Shallow cloning is usually faster, because we no need to calculate references and clone additional objects.

MethodTime per object (ns)Comments
Manual16You should manually realize clone, property by property, field by field. Fastest variant
Manual / MemberwiseClone46Fast variant to clone: call MemberwiseClone inside your class. Should be done manually, but does not require a lot of work.
ShallowClone / Unsafe64Slightly slower than MemberwiseClone due checks for nulls and object types
ShallowClone / Safe64Safe variant based on expressions
CloneExtensions125Implementation of cloning objects on expression trees.
Nuclex.Cloning2498Looks like interesting expression-based implementation with a some caching, but unexpectedly very slow

Performance tricks

We perform a lot of performance tricks to ensure cloning is really fast. Here is some of them:

  • Using a shallow cloning instead of deep cloning if object is safe for this operation
  • Copying an whole object and updating only required fields
  • Special handling for structs (can be copied without any cloning code, if possible)
  • Cloners caching
  • Optimizations for copying simple objects (reduced number of checks to ensure good performance)
  • Special handling of reference count for simple objects, that is faster than default dictionary
  • Constructors analyzing to select best variant of object construction
  • Direct copying of arrays if possible
  • Custom handling of one-dimensional and two-dimensional zero-based arrays (most of arrays in usual code)

License

MIT license

About

Fast object cloner for .NET

Resources

Stars

575 stars

Watchers

13 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

DeepCloner

Library with extenstion to clone objects for .NET. It can deep or shallow copy objects. In deep cloning all object graph is maintained. Library actively uses code-generation in runtime as result object cloning is blazingly fast. Also, there are some performance tricks to increase cloning speed (see tests below). Objects are copied by its' internal structure, no methods or constructuctors are called for cloning objects. As result, you can copy any object, but we don't recommend to copy objects which are binded to native resources or pointers. It can cause unpredictable results (but object will be cloned).

You don't need to mark objects somehow, like Serializable-attribute, or restrict to specific interface. Absolutely any object can be cloned by this library. And this object doesn't have any ability to determine that he is clone (except with very specific methods).

Also, there is no requirement to specify object type for cloning. Object can be casted to inteface or as an abstract object, you can clone array of ints as abstract Array or IEnumerable, even null can be cloned without any errors.

Installation through Nuget:

	Install-Package DeepCloner

Supported Frameworks

DeepCloner works for .NET 4.0 or higher or for .NET Standard 1.3 (.NET Core). .NET Standard version implements only Safe copying variant (slightly slower than standard, see Benchmarks).

Limitation

Library requires Full Trust permission set or Reflection permission (MemberAccess). It prefers Full Trust, but if code lacks of this variant, library seamlessly switchs to slighlty slower but safer variant.

If your code is on very limited permission set, you can try to use another library, e.g. CloneExtensions. It clones only public properties of objects, so, result can differ, but should work better (it requires only RestrictedMemberAccess permission).

Usage

Deep cloning any object:

 var clone = new { Id = 1, Name = "222" }.DeepClone();

With a reference to same object:

 // public class Tree { public Tree ParentTree; }
var t = new Tree();
t.ParentTree = t;
var cloned = t.DeepClone();
Console.WriteLine(cloned.ParentTree == cloned); // True

Or as object:

 var date = DateTime.Now;
var obj = (object)date;
obj.DeepClone().GetType(); // DateTime

Shallow cloning (clone only same object, not objects that object relate to)

 var clone = new { Id = 1, Name = "222" }.ShallowClone();

Cloning to existing object (can be useful for copying constructors, creating wrappers or for keeping references to same object)

public class Derived : BaseClass
{
public Derived(BaseClass parent)
{
parent.DeepCloneTo(this); // now this has every field from parent
}
}

Please, note, that DeepCloneTo and ShallowCloneTo requre that object should be class (it is useless for structures) and derived class must be real descendant of parent class (or same type). In another words, this code will not work:

public class Base {}
public class Derived1 : Base {}
public class Derived2 : Base {}
var b = (Base)new Derived1(); // casting derived to parent
var derived2 = new Derived2();
// will compile, but will throw an exception in runtime, Derived1 is not parent for Derived2
b.DeepCloneTo(derived2); 

Installation

Through nuget:

 Install-Package DeepCloner

Details

You can use deep clone of objects for a lot of situations, e.g.:

  • Emulation of external service or deserialization elimination (e.g. in Unit Testing). When code has received object from external source, code can change it (because object for code is own).
  • ReadOnly object replace. Instead of wrapping your object to readonly object, you can clone object and target code can do anything with it without any restriction.
  • Caching. You can cache data locally and want to ensurce that cached object hadn't been changed by other code

You can use shallow clone as fast, light version of deep clone (if your situation allows that). Main difference between deep and shallow clone in code below:

 // public class A { public B B; }
// public class B { public int X; }
var b = new B { X = 1 };
var a = new A { B = b };
var deepClone = a.DeepClone();
deepClone.B.X = 2;
Console.WriteLine(a.B.X); // 1
var shallowClone = a.ShallowClone();
shallowClone.B.X = 2;
Console.WriteLine(a.B.X); // 2

So, deep cloning is guarantee that all changes of cloned object does not affect original. Shallow clone does not guarantee this. But it faster, because deep clone of object can copy big graph of related objects and related objects of related objects and related related related objects, and... so on...

This library does not call any method of cloning object: constructors, Equals, GetHashCode, propertes - nothing is called. So, it is impossible for cloning object to receive information about cloning, throw an exception or return invalid data. If you need to call some methods after cloning, you can wrap cloning call to another method which will perform required actions.

Extension methods in library are generic, but it is not require to specifify type for cloning. You can cast your objects to System.Object, or to an interface, add fields will be carefully copied to new object.

Performance

Cloning Speed can vary on many factors. This library contains some optimizations, e.g. structs are just copied, arrays also can be copied through Array.Copy if possible. So, real performance will depend on structure of your object.

Tables below, just for information. Simple object with some fields is cloned multiple times. Preparation time (only affect first execution) excluded from tests.

Example of object

var c = new C1 { V1 = 1, O = new object(), V2 = "xxx" };
var c1 = new C1Complex { C1 = c, Guid = Guid.NewGuid(), O = new object(), V1 = 42, V2 = "some test string", Array = new[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 } };

Deep cloning

MethodTime per object (ns)Comments
Manual50You should manually realize cloning. It requires a lot of work and can cause copy-paste errors, but it is fastest variant
DeepClone / Unsafe570This variant is really slower than manual, but clones any object without preparation
DeepClone / Safe760Safe variant based on on expressions
CloneExtensions1800Implementation of cloning objects on expression trees.
NClone2890Not analyzed carefully, but author says that lib has a problem with a cyclic dependencies
Clone.Behave!41890Very slow, also has a dependency to fasterflect
GeorgeCloney6420Has a lot limitations and prefers to clone through BinaryFormatter
Nuclex.Cloningn/aCrashed with a null reference exception
.Net Object FastDeepCloner15030Not analyzed carefully, only for .NET 4.5.1 or higher
DesertOctopus1700Not analyzed. Only for .NET 4.5.2 or higher
BinaryFormatter49100Another way of deep object cloning through serializing/deserializing object. Instead of Json serializers - it maintains full graph of serializing objects and also do not call any method for cloning object. But due serious overhead, this variant is very slow

Shallow cloning Shallow cloning is usually faster, because we no need to calculate references and clone additional objects.

MethodTime per object (ns)Comments
Manual16You should manually realize clone, property by property, field by field. Fastest variant
Manual / MemberwiseClone46Fast variant to clone: call MemberwiseClone inside your class. Should be done manually, but does not require a lot of work.
ShallowClone / Unsafe64Slightly slower than MemberwiseClone due checks for nulls and object types
ShallowClone / Safe64Safe variant based on expressions
CloneExtensions125Implementation of cloning objects on expression trees.
Nuclex.Cloning2498Looks like interesting expression-based implementation with a some caching, but unexpectedly very slow

Performance tricks

We perform a lot of performance tricks to ensure cloning is really fast. Here is some of them:

  • Using a shallow cloning instead of deep cloning if object is safe for this operation
  • Copying an whole object and updating only required fields
  • Special handling for structs (can be copied without any cloning code, if possible)
  • Cloners caching
  • Optimizations for copying simple objects (reduced number of checks to ensure good performance)
  • Special handling of reference count for simple objects, that is faster than default dictionary
  • Constructors analyzing to select best variant of object construction
  • Direct copying of arrays if possible
  • Custom handling of one-dimensional and two-dimensional zero-based arrays (most of arrays in usual code)

License

MIT license

About

Fast object cloner for .NET

Resources

Stars

575 stars

Watchers

13 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

DeepCloner

Library with extenstion to clone objects for .NET. It can deep or shallow copy objects. In deep cloning all object graph is maintained. Library actively uses code-generation in runtime as result object cloning is blazingly fast. Also, there are some performance tricks to increase cloning speed (see tests below). Objects are copied by its' internal structure, no methods or constructuctors are called for cloning objects. As result, you can copy any object, but we don't recommend to copy objects which are binded to native resources or pointers. It can cause unpredictable results (but object will be cloned).

You don't need to mark objects somehow, like Serializable-attribute, or restrict to specific interface. Absolutely any object can be cloned by this library. And this object doesn't have any ability to determine that he is clone (except with very specific methods).

Also, there is no requirement to specify object type for cloning. Object can be casted to inteface or as an abstract object, you can clone array of ints as abstract Array or IEnumerable, even null can be cloned without any errors.

Installation through Nuget:

	Install-Package DeepCloner

Supported Frameworks

DeepCloner works for .NET 4.0 or higher or for .NET Standard 1.3 (.NET Core). .NET Standard version implements only Safe copying variant (slightly slower than standard, see Benchmarks).

Limitation

Library requires Full Trust permission set or Reflection permission (MemberAccess). It prefers Full Trust, but if code lacks of this variant, library seamlessly switchs to slighlty slower but safer variant.

If your code is on very limited permission set, you can try to use another library, e.g. CloneExtensions. It clones only public properties of objects, so, result can differ, but should work better (it requires only RestrictedMemberAccess permission).

Usage

Deep cloning any object:

 var clone = new { Id = 1, Name = "222" }.DeepClone();

With a reference to same object:

 // public class Tree { public Tree ParentTree; }
var t = new Tree();
t.ParentTree = t;
var cloned = t.DeepClone();
Console.WriteLine(cloned.ParentTree == cloned); // True

Or as object:

 var date = DateTime.Now;
var obj = (object)date;
obj.DeepClone().GetType(); // DateTime

Shallow cloning (clone only same object, not objects that object relate to)

 var clone = new { Id = 1, Name = "222" }.ShallowClone();

Cloning to existing object (can be useful for copying constructors, creating wrappers or for keeping references to same object)

public class Derived : BaseClass
{
public Derived(BaseClass parent)
{
parent.DeepCloneTo(this); // now this has every field from parent
}
}

Please, note, that DeepCloneTo and ShallowCloneTo requre that object should be class (it is useless for structures) and derived class must be real descendant of parent class (or same type). In another words, this code will not work:

public class Base {}
public class Derived1 : Base {}
public class Derived2 : Base {}
var b = (Base)new Derived1(); // casting derived to parent
var derived2 = new Derived2();
// will compile, but will throw an exception in runtime, Derived1 is not parent for Derived2
b.DeepCloneTo(derived2); 

Installation

Through nuget:

 Install-Package DeepCloner

Details

You can use deep clone of objects for a lot of situations, e.g.:

  • Emulation of external service or deserialization elimination (e.g. in Unit Testing). When code has received object from external source, code can change it (because object for code is own).
  • ReadOnly object replace. Instead of wrapping your object to readonly object, you can clone object and target code can do anything with it without any restriction.
  • Caching. You can cache data locally and want to ensurce that cached object hadn't been changed by other code

You can use shallow clone as fast, light version of deep clone (if your situation allows that). Main difference between deep and shallow clone in code below:

 // public class A { public B B; }
// public class B { public int X; }
var b = new B { X = 1 };
var a = new A { B = b };
var deepClone = a.DeepClone();
deepClone.B.X = 2;
Console.WriteLine(a.B.X); // 1
var shallowClone = a.ShallowClone();
shallowClone.B.X = 2;
Console.WriteLine(a.B.X); // 2

So, deep cloning is guarantee that all changes of cloned object does not affect original. Shallow clone does not guarantee this. But it faster, because deep clone of object can copy big graph of related objects and related objects of related objects and related related related objects, and... so on...

This library does not call any method of cloning object: constructors, Equals, GetHashCode, propertes - nothing is called. So, it is impossible for cloning object to receive information about cloning, throw an exception or return invalid data. If you need to call some methods after cloning, you can wrap cloning call to another method which will perform required actions.

Extension methods in library are generic, but it is not require to specifify type for cloning. You can cast your objects to System.Object, or to an interface, add fields will be carefully copied to new object.

Performance

Cloning Speed can vary on many factors. This library contains some optimizations, e.g. structs are just copied, arrays also can be copied through Array.Copy if possible. So, real performance will depend on structure of your object.

Tables below, just for information. Simple object with some fields is cloned multiple times. Preparation time (only affect first execution) excluded from tests.

Example of object

var c = new C1 { V1 = 1, O = new object(), V2 = "xxx" };
var c1 = new C1Complex { C1 = c, Guid = Guid.NewGuid(), O = new object(), V1 = 42, V2 = "some test string", Array = new[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 } };

Deep cloning

MethodTime per object (ns)Comments
Manual50You should manually realize cloning. It requires a lot of work and can cause copy-paste errors, but it is fastest variant
DeepClone / Unsafe570This variant is really slower than manual, but clones any object without preparation
DeepClone / Safe760Safe variant based on on expressions
CloneExtensions1800Implementation of cloning objects on expression trees.
NClone2890Not analyzed carefully, but author says that lib has a problem with a cyclic dependencies
Clone.Behave!41890Very slow, also has a dependency to fasterflect
GeorgeCloney6420Has a lot limitations and prefers to clone through BinaryFormatter
Nuclex.Cloningn/aCrashed with a null reference exception
.Net Object FastDeepCloner15030Not analyzed carefully, only for .NET 4.5.1 or higher
DesertOctopus1700Not analyzed. Only for .NET 4.5.2 or higher
BinaryFormatter49100Another way of deep object cloning through serializing/deserializing object. Instead of Json serializers - it maintains full graph of serializing objects and also do not call any method for cloning object. But due serious overhead, this variant is very slow

Shallow cloning Shallow cloning is usually faster, because we no need to calculate references and clone additional objects.

MethodTime per object (ns)Comments
Manual16You should manually realize clone, property by property, field by field. Fastest variant
Manual / MemberwiseClone46Fast variant to clone: call MemberwiseClone inside your class. Should be done manually, but does not require a lot of work.
ShallowClone / Unsafe64Slightly slower than MemberwiseClone due checks for nulls and object types
ShallowClone / Safe64Safe variant based on expressions
CloneExtensions125Implementation of cloning objects on expression trees.
Nuclex.Cloning2498Looks like interesting expression-based implementation with a some caching, but unexpectedly very slow

Performance tricks

We perform a lot of performance tricks to ensure cloning is really fast. Here is some of them:

  • Using a shallow cloning instead of deep cloning if object is safe for this operation
  • Copying an whole object and updating only required fields
  • Special handling for structs (can be copied without any cloning code, if possible)
  • Cloners caching
  • Optimizations for copying simple objects (reduced number of checks to ensure good performance)
  • Special handling of reference count for simple objects, that is faster than default dictionary
  • Constructors analyzing to select best variant of object construction
  • Direct copying of arrays if possible
  • Custom handling of one-dimensional and two-dimensional zero-based arrays (most of arrays in usual code)

License

MIT license

About

Fast object cloner for .NET

Resources

Stars

575 stars

Watchers

13 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Repository files navigation

DeepCloner

Library with extenstion to clone objects for .NET. It can deep or shallow copy objects. In deep cloning all object graph is maintained. Library actively uses code-generation in runtime as result object cloning is blazingly fast. Also, there are some performance tricks to increase cloning speed (see tests below). Objects are copied by its' internal structure, no methods or constructuctors are called for cloning objects. As result, you can copy any object, but we don't recommend to copy objects which are binded to native resources or pointers. It can cause unpredictable results (but object will be cloned).

You don't need to mark objects somehow, like Serializable-attribute, or restrict to specific interface. Absolutely any object can be cloned by this library. And this object doesn't have any ability to determine that he is clone (except with very specific methods).

Also, there is no requirement to specify object type for cloning. Object can be casted to inteface or as an abstract object, you can clone array of ints as abstract Array or IEnumerable, even null can be cloned without any errors.

Installation through Nuget:

	Install-Package DeepCloner

Supported Frameworks

DeepCloner works for .NET 4.0 or higher or for .NET Standard 1.3 (.NET Core). .NET Standard version implements only Safe copying variant (slightly slower than standard, see Benchmarks).

Limitation

Library requires Full Trust permission set or Reflection permission (MemberAccess). It prefers Full Trust, but if code lacks of this variant, library seamlessly switchs to slighlty slower but safer variant.

If your code is on very limited permission set, you can try to use another library, e.g. CloneExtensions. It clones only public properties of objects, so, result can differ, but should work better (it requires only RestrictedMemberAccess permission).

Usage

Deep cloning any object:

 var clone = new { Id = 1, Name = "222" }.DeepClone();

With a reference to same object:

 // public class Tree { public Tree ParentTree; }
var t = new Tree();
t.ParentTree = t;
var cloned = t.DeepClone();
Console.WriteLine(cloned.ParentTree == cloned); // True

Or as object:

 var date = DateTime.Now;
var obj = (object)date;
obj.DeepClone().GetType(); // DateTime

Shallow cloning (clone only same object, not objects that object relate to)

 var clone = new { Id = 1, Name = "222" }.ShallowClone();

Cloning to existing object (can be useful for copying constructors, creating wrappers or for keeping references to same object)

public class Derived : BaseClass
{
public Derived(BaseClass parent)
{
parent.DeepCloneTo(this); // now this has every field from parent
}
}

Please, note, that DeepCloneTo and ShallowCloneTo requre that object should be class (it is useless for structures) and derived class must be real descendant of parent class (or same type). In another words, this code will not work:

public class Base {}
public class Derived1 : Base {}
public class Derived2 : Base {}
var b = (Base)new Derived1(); // casting derived to parent
var derived2 = new Derived2();
// will compile, but will throw an exception in runtime, Derived1 is not parent for Derived2
b.DeepCloneTo(derived2); 

Installation

Through nuget:

 Install-Package DeepCloner

Details

You can use deep clone of objects for a lot of situations, e.g.:

  • Emulation of external service or deserialization elimination (e.g. in Unit Testing). When code has received object from external source, code can change it (because object for code is own).
  • ReadOnly object replace. Instead of wrapping your object to readonly object, you can clone object and target code can do anything with it without any restriction.
  • Caching. You can cache data locally and want to ensurce that cached object hadn't been changed by other code

You can use shallow clone as fast, light version of deep clone (if your situation allows that). Main difference between deep and shallow clone in code below:

 // public class A { public B B; }
// public class B { public int X; }
var b = new B { X = 1 };
var a = new A { B = b };
var deepClone = a.DeepClone();
deepClone.B.X = 2;
Console.WriteLine(a.B.X); // 1
var shallowClone = a.ShallowClone();
shallowClone.B.X = 2;
Console.WriteLine(a.B.X); // 2

So, deep cloning is guarantee that all changes of cloned object does not affect original. Shallow clone does not guarantee this. But it faster, because deep clone of object can copy big graph of related objects and related objects of related objects and related related related objects, and... so on...

This library does not call any method of cloning object: constructors, Equals, GetHashCode, propertes - nothing is called. So, it is impossible for cloning object to receive information about cloning, throw an exception or return invalid data. If you need to call some methods after cloning, you can wrap cloning call to another method which will perform required actions.

Extension methods in library are generic, but it is not require to specifify type for cloning. You can cast your objects to System.Object, or to an interface, add fields will be carefully copied to new object.

Performance

Cloning Speed can vary on many factors. This library contains some optimizations, e.g. structs are just copied, arrays also can be copied through Array.Copy if possible. So, real performance will depend on structure of your object.

Tables below, just for information. Simple object with some fields is cloned multiple times. Preparation time (only affect first execution) excluded from tests.

Example of object

var c = new C1 { V1 = 1, O = new object(), V2 = "xxx" };
var c1 = new C1Complex { C1 = c, Guid = Guid.NewGuid(), O = new object(), V1 = 42, V2 = "some test string", Array = new[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 } };

Deep cloning

MethodTime per object (ns)Comments
Manual50You should manually realize cloning. It requires a lot of work and can cause copy-paste errors, but it is fastest variant
DeepClone / Unsafe570This variant is really slower than manual, but clones any object without preparation
DeepClone / Safe760Safe variant based on on expressions
CloneExtensions1800Implementation of cloning objects on expression trees.
NClone2890Not analyzed carefully, but author says that lib has a problem with a cyclic dependencies
Clone.Behave!41890Very slow, also has a dependency to fasterflect
GeorgeCloney6420Has a lot limitations and prefers to clone through BinaryFormatter
Nuclex.Cloningn/aCrashed with a null reference exception
.Net Object FastDeepCloner15030Not analyzed carefully, only for .NET 4.5.1 or higher
DesertOctopus1700Not analyzed. Only for .NET 4.5.2 or higher
BinaryFormatter49100Another way of deep object cloning through serializing/deserializing object. Instead of Json serializers - it maintains full graph of serializing objects and also do not call any method for cloning object. But due serious overhead, this variant is very slow

Shallow cloning Shallow cloning is usually faster, because we no need to calculate references and clone additional objects.

MethodTime per object (ns)Comments
Manual16You should manually realize clone, property by property, field by field. Fastest variant
Manual / MemberwiseClone46Fast variant to clone: call MemberwiseClone inside your class. Should be done manually, but does not require a lot of work.
ShallowClone / Unsafe64Slightly slower than MemberwiseClone due checks for nulls and object types
ShallowClone / Safe64Safe variant based on expressions
CloneExtensions125Implementation of cloning objects on expression trees.
Nuclex.Cloning2498Looks like interesting expression-based implementation with a some caching, but unexpectedly very slow

Performance tricks

We perform a lot of performance tricks to ensure cloning is really fast. Here is some of them:

  • Using a shallow cloning instead of deep cloning if object is safe for this operation
  • Copying an whole object and updating only required fields
  • Special handling for structs (can be copied without any cloning code, if possible)
  • Cloners caching
  • Optimizations for copying simple objects (reduced number of checks to ensure good performance)
  • Special handling of reference count for simple objects, that is faster than default dictionary
  • Constructors analyzing to select best variant of object construction
  • Direct copying of arrays if possible
  • Custom handling of one-dimensional and two-dimensional zero-based arrays (most of arrays in usual code)

License

MIT license

About

Fast object cloner for .NET

Resources

Stars

575 stars

Watchers

13 watching

Forks

Releases

Packages

Used by

Contributors

Languages