Skip to content

Commit 99904e4

Browse files
committed
Update README.md
1 parent 4879186 commit 99904e4

File tree

1 file changed

+106
-2
lines changed

1 file changed

+106
-2
lines changed

README.md

Lines changed: 106 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ The fastest deep cloning library, supporting anything from <code>.NET 4.6</code>
1717
## ✨ Features
1818

1919
- **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-
- **The Most Correct** - Cloning objects is hard: `<T>`, `abstract`, immutables, read-only, pointers, circular dependencies, deeply nested graphs.. we have over [500 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)
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)
2121
- **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
2222
- **Embeddable** - FastCloner has no dependencies outside the standard library. Source generator and reflection parts can be installed independently
2323
- **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
@@ -101,6 +101,110 @@ Cache can be invalidated to reduce the memory footprint, if needed:
101101
FastCloner.FastCloner.ClearCache();
102102
```
103103

104+
### Generic Classes and Abstract Types
105+
106+
The source generator automatically discovers which concrete types your generic classes and abstract hierarchies are used with:
107+
108+
**Generic types** - The generator scans your codebase for usages like `MyClass<int>` or `MyClass<Customer>` and generates specialized cloning code:
109+
110+
```cs
111+
[FastClonerClonable]
112+
public class Container<T>
113+
{
114+
public T Value { get; set; }
115+
}
116+
117+
// Source generator finds this usage and generates cloning code for Container<int>
118+
var container = new Container<int> { Value = 42 };
119+
var clone = container.FastDeepClone();
120+
```
121+
122+
**Abstract classes** - The generator automatically finds all concrete derived types in your codebase:
123+
124+
```cs
125+
[FastClonerClonable]
126+
public abstract class Animal
127+
{
128+
public string Name { get; set; }
129+
}
130+
131+
public class Dog : Animal
132+
{
133+
public string Breed { get; set; }
134+
}
135+
136+
public class Cat : Animal
137+
{
138+
public bool IsIndoor { get; set; }
139+
}
140+
141+
// Cloning via the abstract type works - the generator discovered Dog and Cat
142+
Animal pet = new Dog { Name = "Buddy", Breed = "Labrador" };
143+
Animal clone = pet.FastDeepClone(); // Returns a cloned Dog
144+
```
145+
146+
### Explicitly Including Types with `[FastClonerInclude]`
147+
148+
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+
```cs
151+
[FastClonerClonable]
152+
[FastClonerInclude(typeof(Customer), typeof(Order))] // Include types used dynamically
153+
public class Wrapper<T>
154+
{
155+
public T Value { get; set; }
156+
}
157+
```
158+
159+
For abstract classes, you can also use `[FastClonerInclude]` to add derived types that aren't in your codebase (e.g., from external assemblies):
160+
161+
```cs
162+
[FastClonerClonable]
163+
[FastClonerInclude(typeof(ExternalPlugin))] // Add external derived types
164+
public abstract class Plugin
165+
{
166+
public string Name { get; set; }
167+
}
168+
```
169+
170+
### Cloning Context with `FastClonerContext`
171+
172+
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+
```cs
175+
public class Customer
176+
{
177+
public string Name { get; set; }
178+
public Address Address { get; set; }
179+
}
180+
181+
public class Address
182+
{
183+
public string City { get; set; }
184+
}
185+
186+
// Create a context and register types to clone
187+
[FastClonerRegister(typeof(Customer), typeof(Address))]
188+
public partial class MyCloningContext : FastClonerContext { }
189+
```
190+
191+
Using the context:
192+
```cs
193+
MyCloningContext ctx = new MyCloningContext();
194+
195+
// Clone with compile-time type safety
196+
Customer clone = ctx.Clone(original);
197+
198+
// Check if a type is handled by this context
199+
bool handled = ctx.IsHandled(typeof(Customer)); // true
200+
201+
// Try to clone (returns false for unregistered types)
202+
if (ctx.TryClone(obj, out var cloned))
203+
{
204+
// Successfully cloned
205+
}
206+
```
207+
104208
## Limitations
105209

106210
- 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.
@@ -137,7 +241,7 @@ You can run the benchmark [locally](https://github.com/lofcz/FastCloner/blob/nex
137241

138242
## Contributing
139243

140-
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 [500 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.
244+
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.
141245

142246
## License
143247

0 commit comments

Comments
 (0)