117 lines
No EOL
2.4 KiB
Markdown
117 lines
No EOL
2.4 KiB
Markdown
# C# Language Design Notes for Feb 20th, 2019
|
|
|
|
## Agenda
|
|
|
|
- Nullable Reference Types: Open LDM Issues https://github.com/dotnet/csharplang/issues/2201
|
|
|
|
## Discussion
|
|
|
|
There are variants of this scenario with `string!` and `string~`. The question is whether we should learn in both branches, or whether we should treat one branch as unreachable.
|
|
|
|
### 'Deliberate' Tests for Nullability
|
|
|
|
This is a continuation of the discussion from the [last meeting](LDM-2019-02-13.md).
|
|
|
|
Proposal: divide into "pure" and "not-pure" null checks. The "pure"
|
|
null checks will affect both branches, but the "not-pure" will only
|
|
affect one branch. Precisely: when a "pure" check is used, the
|
|
nullability state is split for both branches, while a non-pure check
|
|
does not have a "maybe-null" state after split.
|
|
|
|
Proposed deliberate checks:
|
|
|
|
1. `x == null`
|
|
|
|
2. `x != null`
|
|
|
|
3. `(Type)x == null`
|
|
|
|
4. `(Type)x != null`
|
|
|
|
5. `x is null`
|
|
|
|
6. `s is string` (when the type of `s` is `string`)
|
|
|
|
7. `s is string s2` (when the type of `s` is `string`)
|
|
|
|
8. `s is string _` (when the type of `s` is `string`)
|
|
|
|
|
|
Other checks:
|
|
|
|
1. `x is string`
|
|
|
|
2. `x is string s`
|
|
|
|
3. `x is C { Property = 3 }`
|
|
|
|
4. `TryGetValue` (`[NotNullWhenTrue]`)
|
|
|
|
5. `string.IsNullOrEmpty(s)` (`[NotNullWhenFalse]`)
|
|
|
|
6. `x?.ToString() != null`
|
|
|
|
Follow up question: What about `?.` and related operators (e.g., `??`)?
|
|
|
|
An example would be
|
|
|
|
```C#
|
|
void M(string s)
|
|
{
|
|
if (s?.ToString() == null)
|
|
{
|
|
// is `s` maybe null?
|
|
}
|
|
}
|
|
```
|
|
|
|
A corresponding rewrite would be:
|
|
|
|
```C#
|
|
void M(string s)
|
|
{
|
|
if (s == null || s.ToString() == null)
|
|
{
|
|
// s would be maybe-null after this point
|
|
}
|
|
}
|
|
```
|
|
|
|
**Conclusion**
|
|
|
|
Pure:
|
|
|
|
1. `x == null`
|
|
|
|
2. `x != null`
|
|
|
|
3. `(Type)x == null`
|
|
|
|
4. `(Type)x != null`
|
|
|
|
5. `x is null`
|
|
|
|
6. `s is string` (when the type of `s` is `string`)
|
|
|
|
|
|
All conditional access (`?.`, `??`) included
|
|
|
|
Not-Pure
|
|
|
|
1. `x is string`
|
|
|
|
2. `x is string s`
|
|
|
|
3. `x is C { Property = 3 }`
|
|
|
|
4. `TryGetValue` (`[NotNullWhenTrue]`)
|
|
|
|
5. `string.IsNullOrEmpty(s)` (`[NotNullWhenFalse]`)
|
|
|
|
7. `s is string s2` (when the type of `s` is `string`)
|
|
|
|
8. `s is string _` (when the type of `s` is `string`)
|
|
|
|
Switch statement/expression: switch statement treated as
|
|
essentially the equivalent of an `if/else` rewrite. No
|
|
decisions for the switch expression yet. |