Best way to do a discriminated union struct
I have a struct + enum that looks essentially like this.
Is there a better way to do this? Unfortunately I don't think it's possible to do the
MemberNotNullWhen
thing but with just the enum.23 Replies
The enum value can't be null anyway
I mean it would be ideal if something like
[MemberNotNullWhen(ValueKind.String, nameof(StringValue))]
was possibleThat attribute is missing some crucial overloads
You could also consider throwing an exception instead and making the values non nullable
Would avoid storing value types as references
True
wdym?
Like decimal?
Where is it a reference?
You could have it decimal with the default value and throw an exception on get if the type doesn't match
My bad Nullable is a struct
Keep getting that confused
Doesn't making it nullable make it a reference type by default
yes
no?
Because it becomes
Nullable<double>
Nullable is a struct that spoofs nullability
Oh it's a struct?
Hm
If it were truly null, you couldn't use HasValue
Mh
It just stores its null state internally and spoofs all checks
But Nullable does the same thing of throwing an exception when you get the value if it's meant to be null
Yeah I guess I could do that
Doesn't really make the entire thing any prettier but eh
Won't have null warnings
Could also recommend a way of getting the value as object. Sure you have boxxing so not ideal but is say you need to pass it to a method that takes
object
anyway then no loss and you avoid some boiletplateI would like to avoid boxing
Don't use nullables for the fields, make a bunch of
TryGet
for those instead. You could make a match method, if you are ok with allocating a few delegates for a nicer ux. For each of the things it can be, I say you should do getters that either assert or throw if the kind doesn't match. don't use nullables for fields, you already have that info in the ValueKind, plus it's one extra bool for value types. You can do a fixed buffer if you really need to conserve memory, or explicit struct layouts. I personally don't see why the struct should be readonly, I'd just mark the getters readonly
The thing with disciminated unions in C# is that they are clunky if done generically, and Match would need allocations for the delegates.
Code generation with these is a good idea
Or use a packageGitHub
GitHub - mcintyre321/OneOf: Easy to use F#-like ~discriminated~ uni...
Easy to use F#-like ~discriminated~ unions for C# with exhaustive compile time matching - GitHub - mcintyre321/OneOf: Easy to use F#-like ~discriminated~ unions for C# with exhaustive compile time ...
(although I think their type is a class, which is a total letdown)
I was planning on using explicit struct layout anyway, so all the fields for the values wouldn't take up additional space. Asserting that the kind is correct seems like a good option.
For context I'm making a runtime for a dumb interpreted language, and it doesn't need to be super efficient, but I still want to be weary of memory and speed.