Why does C# require source generators for AOT-compatible JSON serialization, whereas languages like Go manage without it? #119024
Replies: 2 comments 3 replies
|
AOT does support reflection, just not all types of reflection. This limitation comes from trimming, which is done as part of AOT compilation. It can also be done without using AOT. See docs here. So then we can ask "why is reflection based System.Text.Json serialization incompatible with trimming and we have to source generators instead". I think this document about the original trimming design and this document about Json serializer sheds some light. In .NET 5 the .NET people were trying to make I don't know enough about Go or Blazor to answer the other parts of your questions. I suspect that Go is more conservative in what reflection data is keep around during linking, based on the conservatism of it's dead code elimination. |
|
I encountered the same confusion when porting C# code to Go; the following is a summary of my discussion with an AI. I think this discussion points to a broader possibility beyond source generators. Go's approach is interesting not because Go has no reflection, but because it has relatively lightweight runtime type metadata that can be queried at runtime. For Native AOT, perhaps there could be a similar third model between full CLR reflection and source-generated code: The idea would be for the compiler/AOT toolchain to automatically generate a compact, trimmable representation of the type information that is actually required by the application: This would not attempt to restore the full CLR reflection system or support arbitrary dynamic assembly loading / runtime code generation. Instead, APIs such as: typeof(User).GetProperties()could potentially be backed by compact AOT metadata rather than requiring the full reflection metadata model. Source generators would still be valuable for highly optimized, scenario-specific code such as JSON serialization, ORM, DI, etc. The difference is that applications and libraries would also have a general-purpose, AOT-friendly way to inspect type metadata without requiring a generator for every scenario. The main questions I see are:
I don't know whether this is technically or architecturally feasible within the current CLR design, but it seems like an interesting direction to explore alongside the source-generator approach. |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
From what I understand, C# relies on reflection for JSON serialization, but reflection isn’t available in AOT compilation. That’s why we have to specify what types we want to serialise on a JSON context. However, languages like Go seem to perform JSON serialization and deserialization without needing to explicitly specify all the types at compile-time. Why is this?
I also know that Blazor, despite using reflection, has a relatively small footprint. How is this possible? What makes this approach different from AOT in C#, and why can't we achieve something similar with AOT applications?
All reactions