91 lines
2.7 KiB
Markdown
91 lines
2.7 KiB
Markdown
|
|
||
|
# C# Language Design Notes for January 14th, 2019
|
||
|
|
||
|
## Agenda
|
||
|
|
||
|
1. Generating null-check for `parameter!`
|
||
|
|
||
|
## Discussion
|
||
|
|
||
|
### Generating null-check for parameter!
|
||
|
|
||
|
Proposal: https://github.com/dotnet/csharplang/pull/2144
|
||
|
|
||
|
*Q: Allow on unconstrained generic parameters?*
|
||
|
|
||
|
**A**: Not a lot of reason to disallow it. `is` currently doesn't work on
|
||
|
unconstrained type parameters, but we view that as a limitation we'd like to
|
||
|
lift.
|
||
|
|
||
|
*Q: Where is the null check for constructors?*
|
||
|
|
||
|
Before or after the base/this calls? Syntactically, it's consistent to leave
|
||
|
it in the constructor body, after the base/this calls. However, this could
|
||
|
cause us to do more work before the exception is eventually thrown.
|
||
|
|
||
|
**A**: In the case where the base/this call would throw anyway, there's not
|
||
|
much difference. But in the case that the base/this are null-safe, putting
|
||
|
the check in the body just delays the exception, which provides little value.
|
||
|
The null check should be the first statement in the method. In general, the
|
||
|
null check should be performed as soon as possible.
|
||
|
|
||
|
*Q: Is there a warning for `void M(string? param!)`?*
|
||
|
|
||
|
`string?` suggests that the method gracefully accepts null, but the feature
|
||
|
immediately throws, which doesn't count.
|
||
|
|
||
|
However, when overriding you may have a `string?` as your base, but your
|
||
|
override only accepts non-nullable `string`.
|
||
|
|
||
|
**A**: Yes. In the case where a user is warned about violating the OHI
|
||
|
contract, the correct decision is to silence the OHI warning, keeping
|
||
|
consistency between the implementation and signature of the method.
|
||
|
|
||
|
*Q: Where is the null check for iterators?*
|
||
|
|
||
|
**A**: Null check in the stub method, as soon as possible (before the yield).
|
||
|
|
||
|
*Q: Can you put it on lambda parameter names?*
|
||
|
|
||
|
**A**: Yes, as long as there are no problems in the syntax. If there
|
||
|
are ambiguities with simple lambda parameter syntax, it can be allowed only
|
||
|
in parenthesized form.
|
||
|
|
||
|
#### Syntax
|
||
|
|
||
|
There's a feature in TypeScript where you can put a `!` after a field name
|
||
|
and that field will be exempt from checking that the field is assigned in
|
||
|
the constructor.
|
||
|
|
||
|
There's concern that `field!` syntax look a lot like `param!` but they would
|
||
|
do almost the opposite thing: `field!` would ignore nulls, while `param!`
|
||
|
would throw on null.
|
||
|
|
||
|
An alternative would be `void M(string! param)` but it's very strange to put
|
||
|
the `!` next to the type but not be part of the type and not be allowed
|
||
|
almost anywhere else that a type is allowed.
|
||
|
|
||
|
Options:
|
||
|
|
||
|
1. Solve both
|
||
|
|
||
|
a. `M(string S!)`, `public string! s`
|
||
|
|
||
|
b. `M(string! S)`, `public string s!`
|
||
|
1. Solve parameters
|
||
|
|
||
|
a. `M(string s!)`
|
||
|
|
||
|
b. `M(string! s)`
|
||
|
|
||
|
1. Solve initialization
|
||
|
|
||
|
a. `public string s!`
|
||
|
|
||
|
b. `public string! s`
|
||
|
|
||
|
1. Do nothing
|
||
|
|
||
|
**Conclusion**
|
||
|
|
||
|
Let's try to do (2a), only `void M(string param!)`, as described by Jared.
|