FastCloner
The fastest deep cloning library for .NET – zero-config, works out of the box.
Install / Use
/learn @lofcz/FastClonerREADME
FastCloner
The fastest and most reliable .NET deep cloning library.
FastCloner is a zero-dependency deep cloning library for .NET, from <code>.NET 4.6</code> to <code>.NET 10+</code>. It combines source generation with optimized reflection fallback, so deep cloning just works.
</div>✨ Features
- The Fastest - Benchmarked to beat all other libraries with third-party independent benchmarks verifying the performance. 300x speed-up vs
Newtonsoft.Jsonand 160x vsSystem.Text.Json - The Most Correct - Built for the cases clone libraries get wrong: polymorphism, circular/shared references, readonly and immutable members, deep graphs, delegates, events, collections... Backed by 800+ tests, with documented limitations
- Hybrid AOT - Uses generated clone code wherever possible, with targeted fallback to the runtime engine only where safety or correctness requires it
- Automatic type discovery - The generator follows usages of generic and abstract types and emits concrete clone paths automatically
- Embeddable - No dependencies outside the standard library. Source generator and reflection parts can be installed independently
- Precise control - Override clone behavior per type or member with
Clone,Reference,Shallow, orIgnore, at compile time or runtime - Selective tracking - FastCloner avoids identity and cycle-tracking overhead by default, but enables it when graph shape or
[FastClonerPreserveIdentity]requires it - Easy Integration -
FastDeepClone()for AOT cloning,DeepClone()for reflection cloning. FastCloner respects standard .NET attributes like[NonSerialized], so you can adopt it without depending on library-specific annotations - Production Ready - Used by projects like Foundatio, Jobbr, TarkovSP, SnapX, and WinPaletter, with over 300K downloads on NuGet
Getting Started
Install the package via NuGet:
dotnet add package FastCloner # Reflection
dotnet add package FastCloner.SourceGenerator # AOT
Clone via Reflection
using FastCloner.Code;
var clone = FastCloner.FastCloner.DeepClone(new { Hello = "world", MyList = new List<int> { 1 } });
For convenience, add the following method to your project. We intentionally don't ship this extension to make switching from/to FastCloner easier:
[return: NotNullIfNotNull(nameof(obj))]
public static T? DeepClone<T>(this T? obj)
{
return FastCloner.FastCloner.DeepClone(obj);
}
Clone via Source Generator
[FastClonerClonable]
public class GenericClass<T>
{
public T Value { get; set; }
}
public class MyClass
{
public string StrVal { get; set; }
}
// [FastClonerClonable] is only required on types where you call .FastDeepClone()
var original = new GenericClass<List<MyClass>> { Value = new List<MyClass> { new MyClass { StrVal = "hello world" } } };
var clone = original.FastDeepClone();
Advanced Usage
Customizing Clone Behavior
FastCloner supports behavior attributes that control how types and members are cloned:
| Behavior | Effect |
|----------|--------|
| Clone | Deep recursive copy |
| Reference | Return original instance unchanged |
| Shallow | MemberwiseClone without recursion |
| Ignore | Return default |
Compile-time (Attributes)
Apply attributes to types or members. Member-level attributes override type-level:
[FastClonerReference] // Type-level: all usages preserve reference
public class SharedService { }
public class MyClass
{
public SharedService Svc { get; set; } // Uses type-level → Reference
[FastClonerBehavior(CloneBehavior.Clone)] // Member-level override → Clone
public SharedService ClonedSvc { get; set; }
[FastClonerIgnore] // → null/default
public CancellationToken Token { get; set; }
[FastClonerShallow] // → Reference copied directly
public ParentNode Parent { get; set; }
}
Shorthand attributes: [FastClonerIgnore], [FastClonerShallow], [FastClonerReference]
Explicit: [FastClonerBehavior(CloneBehavior.X)]
Runtime (Reflection only)
Configure type behavior dynamically. Runtime settings are checked before attributes:
FastCloner.FastCloner.SetTypeBehavior<MySingleton>(CloneBehavior.Reference);
FastCloner.FastCloner.ClearTypeBehavior<MySingleton>(); // Reset one
FastCloner.FastCloner.ClearAllTypeBehaviors(); // Reset all
Note: Changing runtime behavior invalidates the cache. Try to configure once at startup, or use compile-time attributes when possible.
Precedence (highest to lowest)
- Runtime
SetTypeBehavior<T>() - Member-level attribute
- Type-level attribute on member's type
- Default behavior
Cache Management
FastCloner.FastCloner.ClearCache(); // Free memory from reflection cache
Generic Classes and Abstract Types
The source generator automatically discovers which concrete types your generic classes and abstract hierarchies are used with:
Generic types - The generator scans your codebase for usages like MyClass<int> or MyClass<Customer> and generates specialized cloning code:
[FastClonerClonable]
public class Container<T>
{
public T Value { get; set; }
}
// Source generator finds this usage and generates cloning code for Container<int>
var container = new Container<int> { Value = 42 };
var clone = container.FastDeepClone();
Abstract classes - The generator automatically finds all concrete derived types in your codebase:
[FastClonerClonable]
public abstract class Animal
{
public string Name { get; set; }
}
public class Dog : Animal
{
public string Breed { get; set; }
}
public class Cat : Animal
{
public bool IsIndoor { get; set; }
}
// Cloning via the abstract type works - the generator discovered Dog and Cat
Animal pet = new Dog { Name = "Buddy", Breed = "Labrador" };
Animal clone = pet.FastDeepClone(); // Returns a cloned Dog
Explicitly Including Types
When a type is only used dynamically (not visible at compile time), use [FastClonerInclude] to ensure the generator creates cloning code for it:
[FastClonerClonable]
[FastClonerInclude(typeof(Customer), typeof(Order))] // Include types used dynamically
public class Wrapper<T>
{
public T Value { get; set; }
}
For abstract classes, you can also use [FastClonerInclude] to add derived types that aren't in your codebase (e.g., from external assemblies):
[FastClonerClonable]
[FastClonerInclude(typeof(ExternalPlugin))] // Add external derived types
public abstract class Plugin
{
public string Name { get; set; }
}
Custom Cloning Context
For advanced scenarios, create a custom cloning context to explicitly register types you want to clone. This is useful when you need a centralized cloning entry point or want to clone types from external assemblies:
public class Customer
{
public string Name { get; set; }
public Address Address { get; set; }
}
public class Address
{
public string City { get; set; }
}
// Create a context and register types to clone
[FastClonerRegister(typeof(Customer), typeof(Address))]
public partial class MyCloningContext : FastClonerContext { }
Using the context:
MyCloningContext ctx = new MyCloningContext();
// Clone with compile-time type safety
Customer clone = ctx.Clone(original);
// Check if a type is handled by this context
bool handled = ctx.IsHandled(typeof(Customer)); // true
// Try to clone (returns false for unregistered types)
if (ctx.TryClone(obj, out var cloned))
{
// Successfully cloned
}
Nullability Trust
The generator can be instructed to fully trust nullability annotations. When [FastClonerTrustNullability] attribute is applied, FastCloner will skip null checks for non-nullable reference types (e.g., string vs string?), assuming the contract is valid.
[FastClonerClonable]
[FastClonerTrustNullability] // Skip null checks for non-nullable members
public class HighPerformanceDto
{
public string Id { get; set; } // No null check generated
public string? Details { get; set; } // Null check still generated
}
This eliminates branching and improves performance slightly. If a non-nullable property is actually null at runtime, this may result in a NullReferenceException in the generated code.
Safe Handles
When you have a struct that acts as a handle to internal state or a singleton (where identity matters), use [FastClonerSafeHandle]. This tells FastCloner to shallow-copy the readonly fields instead of deep-cloning them, preserving the original internal referen
Related Skills
node-connect
346.8kDiagnose OpenClaw node connection and pairing failures for Android, iOS, and macOS companion apps
frontend-design
107.6kCreate distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, or applications. Generates creative, polished code that avoids generic AI aesthetics.
openai-whisper-api
346.8kTranscribe audio via OpenAI Audio Transcriptions API (Whisper).
qqbot-media
346.8kQQBot 富媒体收发能力。使用 <qqmedia> 标签,系统根据文件扩展名自动识别类型(图片/语音/视频/文件)。
