Skip to content

Deep copy an object: retarget net10.0, drop AutoMapper, fix the benchmark - #2236

Open
vladimir-pecanac-main wants to merge 2 commits into
CodeMazeBlog:mainfrom
vladimir-pecanac-main:seo/84804-csharp-deep-copy-of-object
Open

vladimir-pecanac-main wants to merge 2 commits into
CodeMazeBlog:mainfrom
vladimir-pecanac-main:seo/84804-csharp-deep-copy-of-object

Conversation

@vladimir-pecanac-main

@vladimir-pecanac-main vladimir-pecanac-main commented Sep 23, 2026

Copy link
Copy Markdown
Collaborator

Updates the sample for "Deep Copy and Clone an Object in C#" (csharp-intermediate-topics/DeepCopyInCSharp). This PR touches only this folder.

Changes:

  1. Both projects retargeted from net7.0 to net10.0.
  2. Packages, re-queried on NuGet on 2026-09-23 (newest stable of each):
    • Microsoft.NET.Test.Sdk 17.3.2 to 18.10.1 (the batch block said 18.10.0; 18.10.1 is newer today, so the re-query wins)
    • xunit 2.4.2 to 2.9.3
    • xunit.runner.visualstudio 2.4.5 to 4.0.0
    • coverlet.collector 3.1.2 to 10.0.1
    • BenchmarkDotNet 0.13.5 to 0.15.8
    • Newtonsoft.Json 13.0.3 to 13.0.4
    • DeepCopy 1.0.3 and FastDeepCloner 1.3.6 unchanged: they are the newest published versions.
  3. AutoMapper removed, with its mapper setup in DeepCopyMaker, its benchmark and its test. AutoMapper 12.0.1 raises NU1903 on restore (GHSA-rvv3-g6hj-g44x, CVE-2026-32933, high). Every MIT-licensed version is in the vulnerable range and the patched versions (15.1.1, 16.1.1) are commercially licensed. The article now points readers to the dedicated AutoMapper article instead.
  4. Expression trees: DeepCopyExpressionTrees compiled a new delegate on every call, and the generated code compiled again for the nested Address. The delegate is now built once per type in a static generic cache, and the nested call goes through the same cache.
  5. ConfigOptions.DisableOptimizationsValidator stays in Program.cs, now with a comment saying why. Removing it was tried: BenchmarkDotNet 0.15.8 then refuses to run at all, because FastDeepCloner 1.3.6 ships an assembly built without optimizations and the validator checks every referenced assembly. The switch covers every assembly, so the comment says to run the project with -c Release, which is how the benchmark was run.
  6. Program.cs demonstrations: the shallow copy result used to be overwritten by ten more assignments before anything was printed, so the program could never show the shallow copy output the article prints. Each technique now copies, modifies and prints its own fresh original.
  7. Copy constructors added to Person and Address ([SetsRequiredMembers]), with a test asserting the copied Address is a different instance, and a CopyConstructorBenchmark so the article's copy constructor figure comes from the same run as the others.
  8. Nullable warnings fixed: ArgumentNullException.ThrowIfNull on the inputs, non-null returns where the serializer contract allows it.

Verified locally on SDK 10.0.302, runtime .NET 10.0.10, Windows 10 (AMD Ryzen 5 3600): dotnet build -c Release, 0 warnings, 0 errors. dotnet test, 10 passed, 0 failed. dotnet list package --vulnerable --include-transitive reports no vulnerable packages in either project. The benchmark was re-run in Release on the same machine.

…mark

- Both projects net7.0 to net10.0; BenchmarkDotNet 0.15.8, Newtonsoft.Json 13.0.4,
  Microsoft.NET.Test.Sdk 18.10.1, xunit 2.9.3, xunit.runner.visualstudio 4.0.0,
  coverlet.collector 10.0.1. DeepCopy 1.0.3 and FastDeepCloner 1.3.6 are already the
  newest published versions.
- AutoMapper removed: the package reference, the mapper in DeepCopyMaker, its benchmark
  and its test. Every MIT-licensed AutoMapper version is inside GHSA-rvv3-g6hj-g44x
  (NU1903 on restore) and the patched versions are commercially licensed.
- Expression trees: the compiled delegate is cached per type, and nested objects go
  through the same cache, instead of compiling on every call.
- Program.cs no longer disables the optimizations validator, and each technique now
  copies, modifies and prints its own fresh original, so the shallow copy output is
  reachable again.
- Copy constructors on Person and Address, with a test that the nested Address is not
  shared, and a copy constructor benchmark.
- Nullable warnings fixed with ArgumentNullException.ThrowIfNull on the inputs.
… why

BenchmarkDotNet 0.15.8 refuses to run this benchmark without
ConfigOptions.DisableOptimizationsValidator: FastDeepCloner 1.3.6 ships an assembly
built without optimizations, and the validator checks every referenced assembly.
The switch stays, with a comment saying why and that the project must be run
with -c Release.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant