
# C# Language Design Notes for Oct 17, 2018

## Agenda

1. Open issues with default interface methods
2. Target typed new with default constructors on structs

## Discussion

### Issues in default interface methods

Link: https://github.com/dotnet/csharplang/issues/406

#### Diamond inheritance

We've come down to two options: pick an implementation somewhat arbitrarily,
or produce a runtime exception. The positive about picking one is that we
more strongly provide the guarantee that adding a default method
implementation will not "break" the application. The minus is that there's no
guarantee that the method we actually picked is the correct one.

It's also noted that adding a virtual method to a base class can implement an
interface in the derived class, but you can get the same result just through
current language behavior:

```C#
interface IFoo { void M() { impl; } }
class Derived : Base, IFoo {}

class Base : Base0
{
    public virtual void M() {} // added later
}

class Base0 : IFoo
{
    void IFoo.M() { }
}
```

**Conclusion**

We're going to throw a runtime exception (we want a new exception type) when
there is a runtime diamond and there is no unique most derived
implementation. We've decided that the exception will be thrown at method
resolution time, so the exception would be thrown when taking a delegate to
the target method, rather than when the delegate is invoked. We should note
in documentation when this kind of change could be a source or binary
breaking change.

We'd like to have some method to provide static verification, as long as we
can provide a tool that has access to the runtime environment (like the IL
linker).

#### Permit partial in interface?

Partial methods, in addition to the partial type?

**Conclusion**

Yes, with the same restrictions as in classes.

#### `Main` in an interface?

No reason why not.

#### Confirm that we support public non-virtual methods

Yes, we'll support it.

#### Does an `override` in an interface introduce a new member?

No override keyword in interfaces. This should resolve all listed questions.

#### Properties with a private accessor

We say that private members are not virtual, and the combination of virtual and private is disallowed. But what about a property with a private accessor?

``` c#
interface IA
{
    public virtual int P
    {
        get => 3;
        private set => { } 
    }
}
```

Is this allowed? Is the `set` accessor here `virtual` or not? Can it be overridden where it is accessible? Does the following implicitly implement only the `get` accessor?

``` c#
class C : IA
{
    public int P
    {
        get => 4;
        set { }
    }
}
```

Is the following presumably an error because IA.P.set isn't virtual and also because it isn't accessible?

``` c#
class C : IA
{
    int IA.P
    {
        get => 4;
        set { }
    }
}
```

The first example looks valid, while the last does not. This is resolved
analogously to how it already works in C#.

#### Warning for struct not implementing default method?

This seems like something more suited for an analyzer. It also seems like this
warning could be noisy, since it would fire even if the default interface method
is never called and no boxing will ever occur.

#### When are interface static constructors run?

On the desktop CLR, static methods on interfaces currently run the static
constructor on entry if it has not already been run. It's proposed that we adopt
the same behavior for instance methods.

**Conclusion**

Static constructors are also run on entry to instance methods, if the static
constructor was not `beforefieldinit`, in which case static constructors are
run before access to the first static field.

### Target-typed new()

Can you use new() on anything that has a valid constructor? Like `int`? Or a
tuple?

**Conclusion**

Yes.
