
# C# Language Design Notes for January 7th, 2019

## Agenda

Nullable:

1. Variance in overriding/interface implementation
2. Breaking change in parsing array specifiers 

## Discussion

### variance in overriding/interface implementation

Issues: https://github.com/dotnet/roslyn/issues/23268, https://github.com/dotnet/roslyn/issues/30958

We currently don't support overriding or inheritance with co/contravariance in nullability.

Overriding: we mostly take the signature from the overriding member, not the base.

We could allow nullability variance and then use the most derived implementation.

The problem is if we don't provide a warning on further derivation, another deriver can
"re-loosen the contract."

There doesn't seem to be any problem with an interface implementation, because the safety is provided
in the actual code.

Note: if you override an object-returning method with a dynamic-returning method, we currently
use the dynamic return on callsites, which is a parallel to how nullable works.

Options:

1. Keep stringent invariant rule
2. Allow safe variation on interface implicit implementation only
3. Allow on overrides also, check against base override

**Conclusion**

General agreement on (3). Possibly change tuple names to operate similarly
(use the base's override as the authoritative signature). We will also use
the same rules for explicit interface implementation.

### Breaking change in parsing array specifiers

Issue: https://github.com/dotnet/roslyn/issues/32141

```C#
a ? x is A[][] ? b : c
            // ^ Is this a nullable annotation or part of a ?:
```

Options:

1. Keep decision find another solution for ambiguity
    a. always prefer ternary for back compat, use parens for new meaning in `is`/`as`
2. Change array decision
   a. `?` is a type constructor that's applicable to arrays
   b. Alternate syntax: `?` inside brackets: `a[?][,]` and `a[][,?]`

One of the main problems with changing the array is: `new string[3][];` In
this example, `3` refers to the outer array size, but if we make `string[][]?`
mean "top-level nullable," there's either an inconsistency between the
question mark location (`new string[3]?[]` means *inner* array is nullable)
or we swap the location of the rank (`new string[]?[3]`).

**Conclusion**

Let's try to stick with our original design, and add tie breakers to parsing
to prefer ternary in any ambiguity. Right now we know of problems with array
types in `is` and `as`. There may be more expressions which can end with an
array type, which we will address as we find them.

*Update: This decision was revised in the Jan. 9th meeting.*