-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Description
The following notes are intended to prime the pump for LDM discussion as soon as the LDM has time to take up these issues.
Issues in Default Interface Methods
protected, private protected, and protected internal access (closed)
We tentatively decided to permit protected members in interfaces, admitting we need to specify the meaning of protected, internal, and related access modes. The draft spec permits these but does not describe the meaning. We also need to ensure the runtime agrees to implement them, if needed.
We may need to use protected members in interfaces for explicit interface implementations so that we can generate code for base(T).M() that has access to those explicit implementations: the only way to ensure that we invoke an accessible method is to make such methods protected from the IL point of view.
Here is what runtime spec was saying about accessibility of interface members prior to this feature:
I.8.9.4 Interface type definition
However, since accessibility attributes are relative to the implementing type rather
than the interface itself, all members of an interface shall have public accessibility
We were pretty comfortable with allowing all accessibility attributes that do not include protected access because those were pretty well understood and do not depend on inheritance relationship between types:
I.8.5.3.2 Accessibility of members and nested types
family – accessible to referents that support the same type (i.e., an exact type and all of
the types that inherit from it). For verifiable code (see §I.8.8), there is an additional
requirement that can require a runtime check: the reference shall be made through an
item whose exact type supports the exact type of the referent. That is, the item whose
member is being accessed shall inherit from the type performing the access.
As it turns out the runtime specification for the meaning of inheritance explicitly describes its meaning for interfaces:
I.8.9.8 Type inheritance
Inheritance of types is another way of saying that the derived type guarantees support for all of the type
contracts of the base type. In addition, the derived type usually provides additional functionality or specialized
behavior. A type inherits from a base type by implementing the type contract of the base type. An interface type
implements zero or more other interfaces...
This provides a clear meaning for protected in the runtime specification, which we could mirror in the language specification.
Resolution: We will support these protection levels in interfaces. A protected member in an interface is accessible in all interfaces that derive from it. A protected member in object is not accessible in an interface. A protected member in an interface is accessible through a base(I) qualifier in a class or struct type that implements the interface.
reabstraction (closed)
We specified our intent to permit reabstraction (See https://github.com/dotnet/csharplang/blob/master/proposals/default-interface-methods.md#reabstraction and https://github.com/dotnet/csharplang/blob/master/meetings/2017/LDM-2017-03-21.md#reabstraction) and it is required for Java interop (See https://grokbase.com/t/openjdk/lambda-dev/11cvy137rq/what-does-reabstraction-mean) which is one of our key scenarios. Consequently the only specified form for reabstraction is
void I.M();The abstract modifier is currently explicitly forbidden for explicit implementations. Do we intend to also (for clarity) permit something like
abstract void I.M();Or is the former form sufficient?
We also need to ensure the runtime agrees to implement reabstraction, if needed.
Resolution: We allow reabstraction, and the abstract modifier is required (and permitted) on an abstract implementation. https://github.com/dotnet/csharplang/blob/master/meetings/2019/LDM-2019-03-27.md#reabstraction
explicit interface abstract overrides in classes (closed)
Should we support explicit interface abstract overrides in classes?
Resolution: No. A class must implement every interface method, directly or indirectly. It may, as ever, do so using an abstract method of the class. https://github.com/dotnet/csharplang/blob/master/meetings/2019/LDM-2019-03-27.md#explicit-interface-abstract-overrides-in-classes
Is object.MemberwiseClone() accessible in an interface? (closed)
Resolution: No. Protected members of object are not accessible in interfaces. https://github.com/dotnet/csharplang/blob/master/meetings/2019/LDM-2019-03-27.md#is-objectmemberwiseclone-accessible-in-an-interface
Confirm: static int P { get; set; } is an auto-property with a compiler-generated backing field? (closed)
Confirm: partial on a method declaration implies private, and no access modifier is permitted? (closed)
The existing language specification says that partial methods are implicitly private and that no access modifier is permitted. This item is for the LDM to either confirm that position when they are declared in an interface, permit private on them, require private on them, or something else.
Resolution: Yes, confirmed. https://github.com/dotnet/csharplang/blob/master/meetings/2019/LDM-2019-03-27.md#confirm-that-partial-implies-private-and-no-access-modifier-is-permitted
static fields (closed)
Open Issue: Are static fields and the like permitted in interfaces?
Resolution: Yes.
operators (closed)
Closed Issue: Should operator declarations be permitted in an interface? Probably not conversion operators, but what about others?
Decision: See https://github.com/dotnet/csharplang/blob/master/meetings/2017/LDM-2017-06-27.md for details.
new (closed)
Closed Issue: Should new be permitted on interface member declarations that hide members from base interfaces?
Resolution: new is supported on interface members for a long time. It simply suppresses a warning. See https://github.com/dotnet/csharplang/blob/master/spec/interfaces.md#interface-methods
const (closed)
Open Issue: Should const declarations be permitted in an interface?
Resolution: Yes.
System.Runtime.CompilerServices.RuntimeFeature.DefaultInterfaceImplementation (closed)
Is that the best name for the CLR feature? The CLR feature does much more than just that (e.g. relaxes protection constraints, supports overrides in interfaces, etc). Perhaps it should be called something like "concrete methods in interfaces", or "traits"?
As it stands right now the name of the member is DefaultImplementationsOfInterfaces.
Decision: The LDM doesn't care what its name is.
base(Type).Member for class types (closed)
Open Issue: Confirm base(Type).Member permitted for class types.
We think we approved using the new base(Type) syntax where Type is a class type (e.g. to skip a base and invoke your base's base), but we should explicitly confirm that. Also we should confirm that base(Type).M() might refer to a non-virtual member M. Also we should confirm that there is an accessibility requirement: the M found by this lookup must be accessible where the invocation occurs (i.e. the usual name-lookup constraint).
Decision: Yes.