Closed mikernet closed 2 months ago
Making api behavior varies with nullable annotation isn't really a good idea.
See DI container for an example: GetService<T>
returns nullable. GetRequiredService<T>
returns non-nullable and throws for not found. The two different behaviors are distinguished by different methods.
@huoyaoyuan The problems with having different methods in cases like this was explained above.
At the very least what you are proposing is a language change. A new attribute by itself won't do anything.
Language changes and suggestions should start at https://github.com/dotnet/csharplang/discussions/new/choose
@vcsjones Yes that's a good point. If someone wants to move it, that would be swell.
Background and motivation
There is currently no particularly nice way for methods to know if a reference type generic type parameter is nullable or not. This is desirable in a lot of situations. This new attribute could be applied to a
bool
parameter with a default value so the compiler provides the value.What problem would this solve? Let's demonstrate the problem with this API:
We have a problem here if we want
Write()
to behave differently ifT
is nullable, i.e. let's say it needs to first write a 1 or 0 to indicate whether a value follows or not. So, to solve this issue given the current state of things, you might expand this to:Alright, this is getting a bit unwieldy, but this example doesn't seem too bad yet. Things get worse on the reader side of things though, since methods cannot differ just by generic constraints, so there is no way to define the read methods without additional hacky workarounds:
Unfortunately, we have now introduced an additional problem: let's say I have a data class that I want to write that can accept an unconstrained T:
This is a simplified example of how things can quickly become unusable and a lot of unnecessary complexity starts to develop to handle nullability of generic parameters in some situations.
API Proposal
API Usage
If we could easily flow generic type nullability into methods, then this could be solved as follows:
And now this works as expected:
Alternative Designs
No response
Risks
No response