csharplang/meetings/2018/LDM-2018-10-17.md
Neal Gafter 4e3f2e4ea5
Update LDM-2018-10-17.md (#2246)
Add the details of a question (Properties with a private accessor) so the resolution makes sense in context.
2019-02-19 11:08:20 -08:00

3.7 KiB

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:

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?

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?

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?

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.