dotnet / dotnet/fsharp

Add FSharpType.MakeGenericUnionCase(UnionCaseInfo * Type[])

Open
#8,793 3 comments 4 reactions 0 assignees View on GitHub
Area-Library Feature Request Needs-RFC
Dominant language
F#
Stars
4.3k
Forks
876
Avg merge
4d 22h
Merged PRs (30d)
144

Description

A much missed api for serialization is some way to cache union cases, readers, and constructors when the union is generic (Option/Result/ValueOption etc)

To use `FSharpValue.MakeUnion` or `PreComputeUnionReader/PreComputeUnionTagReader` the `UnionCaseInfo.DeclaringType` needs to be a closed generic type. However the only way — to my knowledge — to get a UnionCaseInfo is via the fairly expensive `FSharpType.GetUnionCases` api which would have to be repeated for each generic instantiation, either causing cache bloat or unnecessary runtime costs. Interestingly GetUnionCases already does not prevent you from passing a generic type definition, it will happily create `UnionCaseInfo[]` based on an open type.

The api hole seems to be around converting a UnionCaseInfo where the DeclaringType is an open type into one with all its arguments saturated.

I propose we add an api that will facilitate that transformation with minimum costs
`FSharpType.MakeGenericUnionCase(UnionCaseInfo * Type[])`

`PreComputeUnionTagReader` should be able to work on open types regardless

And to fully remove excessive caching, `PreComputeUnionReader` would require a similar api addition `PreComputeGenericUnionReader` to accept type arguments in the returned reader function (or use the runtime type from the value).

Implementing this is going to make Newtonsoft.Json, Microsoft.FSharpLu, System.Text.Json and other converters faster by shrinking caches and it allows types like Option to get specialized paths where their open generic cases are just cached on a field.

Thoughts?

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.