# 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.