You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: README.md
+44-3Lines changed: 44 additions & 3 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -19,6 +19,7 @@ The fastest deep cloning library, supporting anything from <code>.NET 4.6</code>
19
19
-**The Fastest** - [Benchmarked](https://github.com/lofcz/FastCloner?tab=readme-ov-file#performance) to beat all other libraries with third-party independent benchmarks verifying the performance. **300x** speed-up vs `Newtonsoft.Json` and **160x** vs `System.Text.Json`
20
20
-**The Most Correct** - Cloning objects is hard: `<T>`, `abstract`, immutables, read-only, pointers, circular dependencies, deeply nested graphs.. we have over [600 tests](https://github.com/lofcz/FastCloner/tree/next/FastCloner.Tests) verifying correct behavior in these cases and we are transparent about the [limitations](https://github.com/lofcz/FastCloner?tab=readme-ov-file#limitations)
21
21
-**Novel Algorithm** - FastCloner recognizes that certain cloning code cannot be generated in certain scenarios and uses highly optimized reflection-based approach instead for these types - this only happens for the members that need this, not entire objects
22
+
-**Zero-Overhead Abstractions** - The generator uses call site analysis to eliminate indirection via inlining of generated methods. This ensures the generated code behaves like a single optimized block, just as if you hand-wrote it for maximum performance.
22
23
-**Embeddable** - FastCloner has no dependencies outside the standard library. Source generator and reflection parts can be installed independently
23
24
-**Gentle & Caring** - FastCloner detects standard attributes like `[NonSerialized]` making it easy to try without polluting codebase with custom attributes. Type usage graph for generics is built automatically producing performant cloning code without manual annotations
24
25
-**Easy Integration** - `FastDeepClone()` for AOT cloning, `DeepClone()` for reflection cloning. That's it!
@@ -143,7 +144,7 @@ Animal pet = new Dog { Name = "Buddy", Breed = "Labrador" };
143
144
Animalclone=pet.FastDeepClone(); // Returns a cloned Dog
144
145
```
145
146
146
-
### Explicitly Including Types with `[FastClonerInclude]`
147
+
### Explicitly Including Types
147
148
148
149
When a type is only used dynamically (not visible at compile time), use `[FastClonerInclude]` to ensure the generator creates cloning code for it:
149
150
@@ -167,7 +168,7 @@ public abstract class Plugin
167
168
}
168
169
```
169
170
170
-
### Cloning Context with `FastClonerContext`
171
+
### Custom Cloning Context
171
172
172
173
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:
173
174
@@ -205,6 +206,37 @@ if (ctx.TryClone(obj, out var cloned))
205
206
}
206
207
```
207
208
209
+
### Nullability Trust
210
+
211
+
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.
212
+
213
+
```csharp
214
+
[FastClonerClonable]
215
+
[FastClonerTrustNullability] // Skip null checks for non-nullable members
216
+
publicclassHighPerformanceDto
217
+
{
218
+
publicstringId { get; set; } // No null check 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.
224
+
225
+
### Safe Handles
226
+
227
+
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 references.
228
+
229
+
```csharp
230
+
[FastClonerSafeHandle]
231
+
publicstructMyHandle
232
+
{
233
+
privatereadonlyobject_internalState; // Preserved (shared), not deep cloned
234
+
publicintValue; // Cloned normally
235
+
}
236
+
```
237
+
238
+
This is the default behavior for system types like `System.Net.Http.Headers.HeaderDescriptor` to prevent breaking internal framework logic. Use this attribute if your custom structs behave similarly.
239
+
208
240
## Limitations
209
241
210
242
- Cloning unmanaged resources, such as `IntPtr`s may result in side-effects, as there is no metadata for the length of buffers such pointers often point to.
@@ -239,10 +271,19 @@ Intel Core i7-8700 CPU 3.20GHz (Max: 3.19GHz) (Coffee Lake), 1 CPU, 12 logical a
239
271
240
272
You can run the benchmark [locally](https://github.com/lofcz/FastCloner/blob/next/FastCloner.Benchmark/BenchMinimal.cs) to verify the results. There are also [third-party benchmarks](https://github.com/AnderssonPeter/Dolly?tab=readme-ov-file#benchmarks) in some of the competing libraries confirming these results.
241
273
274
+
### Build Times & IDE Performance
275
+
276
+
FastCloner's source generator is carefully engineered for zero impact on IDE responsiveness and swift build times.
277
+
278
+
-**Tiered Caching**: We use `ForAttributeWithMetadataName` for highly efficient filtering and strictly separate syntax analysis from code generation.
279
+
-**Smart Models**: Roslyn symbols are immediately projected into lightweight, cache-friendly `TypeModel` records. The generator never holds onto compilation symbols, allowing the incremental pipeline to perfectly cache previous results.
280
+
-**No Compilation Trashing**: We avoid expensive `CompilationProvider` combinations that break generator caching. Code generation only re-runs when your data models actually change, not on every keystroke or unrelated edit.
281
+
-**Allocation Free**: `EquatableArray` collections ensure that change detection is instant and creates no garbage collection pressure.
282
+
242
283
## Contributing
243
284
244
285
If you are looking to add new functionality, please open an issue first to verify your intent is aligned with the scope of the project. The library is covered by over [600 tests](https://github.com/lofcz/FastCloner/tree/next/src/FastCloner.Tests), please run them against your work before proposing changes. When reporting issues, providing a minimal reproduction we can plug in as a new test greatly reduces turnaround time.
245
286
246
287
## License
247
288
248
-
This library is licensed under the [MIT](https://github.com/lofcz/FastCloner/blob/next/LICENSE) license. 💜
289
+
This library is licensed under the [MIT](https://github.com/lofcz/FastCloner/blob/next/LICENSE) license. 💜
0 commit comments