Skip to content

Conversation

@RexJaeschke
Copy link
Contributor

@RexJaeschke RexJaeschke commented Dec 5, 2022

Re the MS proposal: The main challenge when reading it was the (misleading) occurrence of the modifier override in numerous examples and narrative. As best as I can tell, this modifier is not actually permitted on any interface member. Instead, overriding is achieved via explicit implementation.

There is one open question, which has to do with the topic "Base Interface Invocations," for which the decision "Decided on base(N.I1<T>).M(s)" was made. However, as far as I can tell, support for this was not added to the V8 compiler. Can someone please confirm (or refute) that.

BTW, I think the proposal is misnamed: it really applies to all interface function members (properties, indexers, and events as well), not just methods. (it also allows nested types.)

Note: No spec changes are needed to support entry point Main in an interface. Any non-generic type containing a Main method with void/int return and no/one string[] parameter list is already permitted, which not only allows Main in a struct or class, but now also in an interface.

As of V7, the descriptions of the various member kinds has been located in classes.md, with augmenting and/or overriding text in structs.md, with pointers from structs.md back into classes.md, and that continues. However, now that many members kinds can have implementations in interfaces as well, I've added an intro para to the start of most member sections in classes.md, which contains forward pointers to that member kind's occurrence in structs.md and interfaces.md, as appropriate.

Fixes #982 (which reinstates abstract override.)

@RexJaeschke RexJaeschke added this to the C# 8.0 milestone Dec 5, 2022
@RexJaeschke RexJaeschke self-assigned this Dec 5, 2022
@RexJaeschke RexJaeschke marked this pull request as draft December 5, 2022 13:54
@RexJaeschke
Copy link
Contributor Author

RexJaeschke commented Dec 6, 2022

Depending how PR #680 is resolved, some tweaks might be needed with this PR.

As at 2025-05-03, that PR is still pending, and is tied to the review of this PR.

@BillWagner BillWagner force-pushed the default-interface-function-members branch from 84a1703 to caba5c7 Compare February 6, 2023 13:52
@RexJaeschke RexJaeschke added the type: feature This issue describes a new feature label Jul 22, 2023
@BillWagner BillWagner force-pushed the default-interface-function-members branch from caba5c7 to dc8d7a0 Compare September 25, 2023 20:54
@BillWagner
Copy link
Member

rebased on the latest draft-v8 on 09-23-2023

@KalleOlaviNiemitalo
Copy link
Contributor

Should the references to "C# implementations targeting the CLI" be changed somehow because the ECMA standard CLI does not support default interface members? Possible answers include:

  • Remove them; C# 8 implementations cannot target "the CLI".
  • Change them to say "targeting a CLI with extensions" or the like.
  • Keep them; a C# implementation can still target the standard CLI, although the mapping may become complex or inefficient or have restrictions (like not supporting dynamic loading of assemblies that were not provided at build time).

@RexJaeschke RexJaeschke added the Review: pending Proposal is available for review label Oct 13, 2023
@RexJaeschke RexJaeschke removed their assignment Oct 22, 2023
@RexJaeschke RexJaeschke marked this pull request as ready for review January 11, 2024 14:00
@gafter gafter self-assigned this Jan 16, 2024
@RexJaeschke
Copy link
Contributor Author

Re @KalleOlaviNiemitalo's concern about the Ecma CLI standard not supporting default interface function members, we previously made a related change to the draft-v8 Introduction, which in V7, said:

... Although Microsoft’s implementation of C# relies on CLI for library and run-time support, other implementations of C# need not, provided they support an alternate way of getting at the minimum CLI features required by this C# standard (see Annex C).

It now says:

... Although Microsoft’s implementation of C# relies on CLI for library and run-time support, other implementations of C# need not, provided they support the features and API required by this C# Standard (see Annex C).

I think that allows us to say nothing more for this feature with regard to the CLI.

@gafter
Copy link
Member

gafter commented Dec 15, 2024

I don't recall why this is assigned to me. Is it for general review, or to answer the question about base(T).M()? If the latter, see the following:

In short, the base(T).M() syntax has not been added to the language yet.

@BillWagner
Copy link
Member

@gafter

I don't recall why this is assigned to me. Is it for general review, or to answer the question about base(T).M()?

Going from memory, but I believe as a general reviewer.

@RexJaeschke
Copy link
Contributor Author

closed and reopened to get all tests to run

@RexJaeschke RexJaeschke added the meeting: priority Review before meeting. Merge, merge with issues, or reject at the next TC49-TC2 meeting label Jun 10, 2025
@jskeet
Copy link
Contributor

jskeet commented Jun 11, 2025

@RexJaeschke and @BillWagner could you look at resolving the conflict?

I'm not sure whether we can realistically expect most members to have reviewed this before the meeting later today though. (I'll see whether I can find time, but I'm prioritizing #606.)

@BillWagner BillWagner force-pushed the default-interface-function-members branch from 22549fb to efb69e5 Compare June 11, 2025 13:57
@BillWagner
Copy link
Member

@RexJaeschke and @BillWagner could you look at resolving the conflict?

I'm not sure whether we can realistically expect most members to have reviewed this before the meeting later today though. (I'll see whether I can find time, but I'm prioritizing #606.)

@jskeet I did a full rebase.

My main goal in prioritizing this for today's meeting is to get it assigned to someone for next meeting. I agree that there isn't time to get it reviewed thoroughly.

@jskeet
Copy link
Contributor

jskeet commented Jun 25, 2025

@BillWagner Looking again, did we get as far as assigning it during the last meeting? We spent quite a bit of time talking about prose vs grammar for constraints, but we didn't record the next step...

Copy link
Member

@BillWagner BillWagner left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated for most review comments.
I did some investigation for https://github.com/dotnet/csharpstandard/pull/681/files#r2386725345

My notes are the last comment in that thread.

Update rules for interface member lookup and mapping (or implementing) an interface member.

Add C# 10 note

For our future selves.
@BillWagner BillWagner force-pushed the default-interface-function-members branch from bf3c327 to acfdffe Compare October 2, 2025 15:10
@BillWagner
Copy link
Member

BillWagner commented Oct 2, 2025

@Nigel-Ecma @jnm2

The changes in the latest commit address the concepts in #681 (comment)

The significant changes in the last commit:

  • In 19.6.1, Lines 721 - 724: Add rules for interface member implementation on public, non-public, and non-accessible interface members.
  • In 19.6.2, Lines 795-796: Add requirement that non-public interface members can only be overridden using explicit interface members.
  • I didn't update 12.5.1 (lookup rules) because I think lines 377-378 already does what we need:
  • If M is a constant, field, property, event, enumeration member, or type declaration, then all members declared in an interface declaration are removed from the set.
  • If M is a method, then all non-method members declared in an interface declaration are removed from the set, and all methods with the same signature as M declared in an interface declaration are removed from the set.

This clause augments the description of nested types in classes [§15.3.9](classes.md#1539-nested-types) for nested types declared in interfaces.
It is an error to declare a class type, struct type, or enum type within the scope of a type parameter that was declared with a *variance_annotation* ([§19.2.3.1](interfaces.md#19231-general)).
Copy link
Contributor

@KalleOlaviNiemitalo KalleOlaviNiemitalo Oct 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This may require changing the wording in §7.7.1 (Scopes / General). In the following, the outer T is hidden by the inner T.

interface IOuter<out T>
{
    interface IInner<T>
    {
        class C { }
    }
}

§7.7.1 currently says:

The scope of a name is the region of program text within which it is possible to refer to the entity declared by the name without qualification of the name. Scopes can be nested, and an inner scope may redeclare the meaning of a name from an outer scope. (This does not, however, remove the restriction imposed by §7.3 that within a nested block it is not possible to declare a local variable or local constant with the same name as a local variable or local constant in an enclosing block.) The name from the outer scope is then said to be hidden in the region of program text covered by the inner scope, and access to the outer name is only possible by qualifying the name.

Within the definition of interface IInner<T> , it is not possible to refer to the T type parameter of IOuter. According to this wording then, the definition of class C is not in the scope of the outer T.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Alternatively, this might be solved by adding "including any nested scopes" to the restriction here.

Copy link
Contributor

@jskeet jskeet left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've reviewed the changes as best I can, one commit at a time... but it's getting really tricky. (Things I've noticed in one commit have been fixed in a later one.)

I think we should aim to merge the PR as-is by the end of the upcoming meeting, with comments for things that still need resolving - it'll make it much easier to review. The downside is it'll be harder to see "the totality of changes for this feature" of course.

@Nigel-Ecma
Copy link
Contributor

I agree with @jskeet:

I've reviewed the changes as best I can, one commit at a time... but it's getting really tricky. (Things I've noticed in one commit have been fixed in a later one.)

I think we should aim to merge the PR as-is by the end of the upcoming meeting, with comments for things that still need resolving - it'll make it much easier to review. The downside is it'll be harder to see "the totality of changes for this feature" of course.

@BillWagner – could you please tag the draft-v8 branch before & after you merge this so we can check out the two commits locally & diff them to see "the totality of changes for this feature"? Of course we can do such diffs anyway, the tags just save locating the commit UUIDs.

@BillWagner BillWagner dismissed Nigel-Ecma’s stale review October 22, 2025 19:26

Agreed to merge in 10/22 meeting.

@BillWagner BillWagner merged commit c85ebc3 into dotnet:draft-v8 Oct 22, 2025
6 checks passed
@BillWagner BillWagner deleted the default-interface-function-members branch October 22, 2025 19:27
BillWagner added a commit to BillWagner/docs that referenced this pull request Oct 23, 2025
We merged dotnet/csharpstandard#681 at the October meeting.
BillWagner added a commit to dotnet/docs that referenced this pull request Oct 23, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

meeting: priority Review before meeting. Merge, merge with issues, or reject at the next TC49-TC2 meeting Review: pending Proposal is available for review type: feature This issue describes a new feature

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Reinstate "abstract override"

7 participants