You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Adding support for default interface function members (#681)
* Allow interfaces as well
* support default interface function members
* support default interface function members
* Update classes.md
* Update interfaces.md
* Update interfaces.md
* add annotation to new examples
* first pass at fixing references
* find link errors part 2
* word converter warnings
Enclosing a paragraph in brackets breaks the word converter. It looks for a link.
* minor tweaks
* Fix editorial nits
* fix link
* fix link
* Move interface descriptions to interfaces.
Some of the descriptions of interface members were in the class clause. Move them to the interface clause. Also, instead of adding a link from classes to interfaces and structs into each sub-clause, provide one blanket statement at the beginning of classes.md.
* Apply suggestions from code review
Co-authored-by: Joseph Musser <[email protected]>
* edit pass on interfaces
Clean up the interfaces markdown file
* Rewrite most specific implementation rule
This reads more consistently to me.
Also, disallow reabstraction of interface methods in class types.
* lint issues
* Apply suggestions from code review
Co-authored-by: Jon Skeet <[email protected]>
* Respond to previous meeting feedback
Make all edits except grammar changes.
* fix grammar and test issues
Remove interface indexer grammar (it's the same as class grammar).
Fix test issues (typo `constant` => `Constant`
* final pass at comments
* Apply suggestions from code review
Co-authored-by: Nigel-Ecma <[email protected]>
* review comments, plus some noodling
I need to clean up the notes from lines 578-587 to proper normative language.
* Add normative rules for interface member resolution
Finalize the normative language for resolution of members defined in an interface.
* first set of post-meeting updates.
* respond to review feedback.
* Clarify more on access to interface members
Clarify the rules on overriding interface members with implementations, and on accessing members with an implementation in an interface.
* Apply suggestions from code review
Co-authored-by: Joseph Musser <[email protected]>
* update anchor
* update xrefs
* more anchor cleanup
* Update grammar tests for DIM
* mostly grammar edits
Edit files other than interfaces post meeting
* Updates from review at 9/25 meeting
Updates terminology from 'override' to 'implementation' for interface members, clarifies rules for hiding and explicitly implementing inherited members, and improves examples and notes for interface member access and inheritance. Adds details about the use of the 'new' modifier and compiler warnings, and refines explanations of most specific implementation in diamond inheritance scenarios.
* lint
* Address review comments
Address review comments from Nigel on 9/25-26
* Apply suggestions from code review
Co-authored-by: Joseph Musser <[email protected]>
* Edits per review
Respond to edits except for the rabbit hole opened by https://github.com/dotnet/csharpstandard/pull/681/files#r2386725345
* fix test
* fix build issue.
* Update rules for lookup and mapping
Update rules for interface member lookup and mapping (or implementing) an interface member.
Add C# 10 note
For our future selves.
* Apply suggestions from code review
Co-authored-by: Jon Skeet <[email protected]>
* Apply suggestions from code review
* Apply suggestions from code review
Co-authored-by: Nigel-Ecma <[email protected]>
* Apply suggestions from code review
---------
Co-authored-by: Bill Wagner <[email protected]>
Co-authored-by: Joseph Musser <[email protected]>
Co-authored-by: Jon Skeet <[email protected]>
Co-authored-by: Nigel-Ecma <[email protected]>
Copy file name to clipboardExpand all lines: standard/basic-concepts.md
+33-9Lines changed: 33 additions & 9 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -78,7 +78,7 @@ There are several different types of declaration spaces, as described in the fol
78
78
- Within all compilation units of a program, *namespace_member_declaration*s with no enclosing *namespace_declaration* are members of a single combined declaration space called the ***global declaration space***.
79
79
- Within all compilation units of a program, *namespace_member_declaration*s within *namespace_declaration*s that have the same fully qualified namespace name are members of a single combined declaration space.
80
80
- Each *compilation_unit* and *namespace_body* has an ***alias declaration space***. Each *extern_alias_directive* and *using_alias_directive* of the *compilation_unit* or *namespace_body* contributes a member to the alias declaration space ([§14.5.2](namespaces.md#1452-using-alias-directives)).
81
-
- Each non-partial class, struct, or interface declaration creates a new declaration space. Each partial class, struct, or interface declaration contributes to a declaration space shared by all matching parts in the same program ([§16.2.4](structs.md#1624-partial-modifier)). Names are introduced into this declaration space through *class_member_declaration*s, *struct_member_declaration*s, *interface_member_declaration*s, or *type_parameter*s. Except for overloaded instance constructor declarations and static constructor declarations, a class or struct cannot contain a member declaration with the same name as the class or struct. A class, struct, or interface permits the declaration of overloaded methods and indexers. Furthermore, a class or struct permits the declaration of overloaded instance constructors and operators. For example, a class, struct, or interface may contain multiple method declarations with the same name, provided these method declarations differ in their signature ([§7.6](basic-concepts.md#76-signatures-and-overloading)). Note that base classes do not contribute to the declaration space of a class, and base interfaces do not contribute to the declaration space of an interface. Thus, a derived class or interface is allowed to declare a member with the same name as an inherited member. Such a member is said to ***hide*** the inherited member.
81
+
- Each non-partial class, struct, or interface declaration creates a new declaration space. Each partial class, struct, or interface declaration contributes to a declaration space shared by all matching parts in the same program ([§16.2.4](structs.md#1624-partial-modifier)). Names are introduced into this declaration space through *class_member_declaration*s, *struct_member_declaration*s, *interface_member_declaration*s, or *type_parameter*s. Except for overloaded instance constructor declarations and static constructor declarations, a class, struct, or interface cannot contain a member declaration with the same name as the class, struct, or interface. A class, struct, or interface permits the declaration of overloaded methods and indexers. Furthermore, a class or struct permits the declaration of overloaded instance constructors and operators. For example, a class, struct, or interface may contain multiple method declarations with the same name, provided these method declarations differ in their signature ([§7.6](basic-concepts.md#76-signatures-and-overloading)). Note that base classes do not contribute to the declaration space of a class, and base interfaces do not contribute to the declaration space of an interface. Thus, a derived class or interface is allowed to declare a member with the same name as an inherited member. Such a member is said to ***hide*** the inherited member.
82
82
- Each delegate declaration creates a new declaration space. Names are introduced into this declaration space through parameters (*fixed_parameter*s and *parameter_array*s) and *type_parameter*s.
83
83
- Each enumeration declaration creates a new declaration space. Names are introduced into this declaration space through *enum_member_declarations*.
84
84
- Each method declaration, property declaration, property accessor declaration, indexer declaration, indexer accessor declaration, operator declaration, instance constructor declaration, anonymous function, and local function creates a new declaration space called a ***local variable declaration space***. Names are introduced into this declaration space through parameters (*fixed_parameter*s and *parameter_array*s) and *type_parameter*s. The set accessor for a property or an indexer introduces the name `value` as a parameter. The body of the function member, anonymous function, or local function, if any, is considered to be nested within the local variable declaration space. When a local variable declaration space and a nested local variable declaration space contain elements with the same name, within the scope of the nested local name, the outer local name is hidden ([§7.7.1](basic-concepts.md#771-general)) by the nested local name.
@@ -268,7 +268,7 @@ When access to a particular member is allowed, the member is said to be ***acces
268
268
The ***declaredaccessibility*** ofamembercanbeoneofthefollowing:
269
269
270
270
- Public, whichisselectedbyincludinga `public` modifierinthememberdeclaration. Theintuitivemeaningof `public` is “accessnotlimited”.
271
-
- Protected, whichisselectedbyincludinga `protected` modifierinthememberdeclaration. Theintuitivemeaningof `protected` is “accesslimitedtothecontainingclassortypesderivedfromthecontainingclass”.
271
+
- Protected, whichisselectedbyincludinga `protected` modifierinthememberdeclaration. Theintuitivemeaningof `protected` is “accesslimitedtothecontainingclassorinterface, orclassesorinterfacesderivedfromthecontainingtype”.
272
272
- Internal, whichisselectedbyincludingan `internal` modifierinthememberdeclaration. Theintuitivemeaningof `internal` is “accesslimitedtothisassembly”.
- Privateprotected, whichisselectedbyincludingbotha `private` anda `protected` modifierinthememberdeclaration. Theintuitivemeaningof `privateprotected` is “accessiblewithinthisassemblybythecontainingclassandtypesderivedfromthecontainingclass.”
@@ -402,7 +402,7 @@ As described in [§7.4](basic-concepts.md#74-members), all members of a base cla
402
402
403
403
### 7.5.4 Protected access
404
404
405
-
When a `protected` or `private protected` instance member is accessed outside the program text of the class in which it is declared, and when a `protected internal` instance member is accessed outside the program text of the program in which it is declared, the access shall take place within a class declaration that derives from the class in which it is declared. Furthermore, the access is required to take place *through* an instance of that derived class type or a class type constructed from it. This restriction prevents one derived class from accessing protected members of other derived classes, even when the members are inherited from the same base class.
405
+
When a `protected` or `private protected` instance member is accessed outside the program text of the class in which it is declared, and when a `protected internal` instance member is accessed outside the program text of the program in which it is declared, the access shall take place within a class declaration that derives from the class in which it is declared. Furthermore, the access is required to take place *through* an instance of that derived class type or a class type constructed from it. This restriction prevents one derived class from accessing protected members of other derived classes, even when the members are inherited from the same base class. Instance interface members defined with `protected` or `private protected` access cannot be accessed from a `class` or `struct` that implements that interface; thesecanbeaccessedonlyfromderivedinterfaces. However, `class` and `struct` types can define overridden `protected` instance members declared in an interface it implements.
406
406
407
407
Let `B` be a base classthat declares a protected instance member `M`, and let `D` be a class that derives from `B`. Within the *class_body* of `D`, access to `M` can take one of the following forms:
408
408
@@ -781,9 +781,9 @@ When a name in an inner scope hides a name in an outer scope, it hides all overl
- If `x` is zero and the *namespace_or_type_name* appears within a generic method declaration ([§15.6](classes.md#156-methods)) but outside the *attributes* of its *method-header*, and if that declaration includes a type parameter ([§15.2.3](classes.md#1523-type-parameters)) with name `I`, then `R₀` refers to that type parameter.
916
-
- Otherwise, if the *namespace_or_type_name* appears within a type declaration, then for each instance type `T` ([§15.3.2](classes.md#1532-the-instance-type)), starting with the instance type of that type declaration and continuing with the instance type of each enclosing classor struct declaration (if any):
916
+
- Otherwise, if the *namespace_or_type_name* appears within a type declaration, then for each instance type `T` ([§15.3.2](classes.md#1532-the-instance-type)), starting with the instance type of that type declaration and continuing with the instance type of each enclosing class, struct, or interface declaration (if any):
917
917
- If `x` is zero and the declaration of `T` includes a type parameter with name `I`, then `R₀` refers to that type parameter.
918
-
- Otherwise, if the *namespace_or_type_name* appears within the body of the type declaration, and `T` or any of its base types contain a nested accessible type having name `I` and `x` type parameters, then `R₀` refers to that type constructed with the given type arguments. If there is more than one such type, the type declared within the more derived type is selected.
918
+
- Otherwise, if the *namespace_or_type_name* appears within the body of the type declaration, and `T` or any of its base types contain a nested accessible type having name `I` and `x` type parameters, then `R₀` refers to that type constructed with the given type arguments. If there is more than one such type, the type declared within the more derived type is selected. It is a compiler error if no type is more derived than all others.
919
919
> *Note*: Non-type members (constants, fields, methods, properties, indexers, operators, instance constructors, finalizers, and static constructors) and type members with a different number of type parameters are ignored when determining the meaning of the *namespace_or_type_name*. *end note*
920
920
- Otherwise, for each namespace `N`, starting with the namespace in which the *namespace_or_type_name* occurs, continuing with each enclosing namespace (if any), and ending with the global namespace, the following steps are evaluated until an entity is located:
921
921
- If `x` is zero and `I` is the name of a namespace in `N`, then:
@@ -945,7 +945,7 @@ For each repetition `n`, where `1 ≤ n ≤ k`, its resolution, `Rₙ`; which in
945
945
946
946
- If `x` is zero and `Rₚ` refers to a namespace and `Rₚ` contains a nested namespace with name `I`, then `Rₙ` refers to that nested namespace.
947
947
- Otherwise, if `Rₚ` refers to a namespace and `Rₚ` contains an accessible type having name `I` and `x` type parameters, then `Rₙ` refers to that type constructed with the given type arguments.
948
-
- Otherwise, if `Rₚ` refers to a (possibly constructed) classor struct type and `Rₚ` or any of its base classes contain a nested accessible type having name `I` and `x` type parameters, then `Rₙ` refers to that type constructed with the given type arguments. If there is more than one such type, the type declared within the more derived type is selected.
948
+
- Otherwise, if `Rₚ` refers to a (possibly constructed) class, struct, or interface type and `Rₚ` or any of its base types contain a nested accessible type having name `I` and `x` type parameters, then `Rₙ` refers to that type constructed with the given type arguments. If there is more than one such type, the type declared within the more derived type is selected. It is a compiler error if no type is more derived than all others.
949
949
> *Note*: If the meaning of `T.I`, for some type `T`, is being determined as part of resolving the base class specification of `T` then the direct base class of `T` is considered to be `object` ([§15.2.4.2](classes.md#15242-base-classes)). *end note*
950
950
- Otherwise, the *namespace_or_type_name* is invalid and a compile-time error occurs.
951
951
@@ -956,6 +956,30 @@ A *namespace_or_type_name* is permitted to reference a static class ([§15.2.2.4
956
956
- The *namespace_or_type_name* is the `T` in a *namespace_or_type_name* of the form `T.I`, or
957
957
- The *namespace_or_type_name* is the `T` in a *typeof_expression* ([§12.8.18](expressions.md#12818-the-typeof-operator)) of the form `typeof(T)`
> publicvoidTest() { NestedClass.M(); } // ambiguity between A.NestedClass and B.NestedClass
976
+
> }
977
+
> ```
978
+
>
979
+
>Intheexampleabove, thecallto `NestedClass.M()` in `C.Test()` isambiguousbetween `B.NestedClass.M()` and `A.NestedClass.M()` becauseneitherismorederivedthantheother. Anexplicitreferencetoeither `A.NestedClass.M()` or `B.NestedClass.M()` isrequiredtoresolvetheambiguity.
0 commit comments