Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 6 additions & 3 deletions standard/classes.md
Original file line number Diff line number Diff line change
@@ -1,24 +1,24 @@
# 15 Classes

Check warning on line 2 in standard/classes.md

View workflow job for this annotation

GitHub Actions / Markdown to Word Converter

standard/classes.md#L2

MDC032::Line length 83 > maximum 81
## 15.1 General

Check warning on line 3 in standard/classes.md

View workflow job for this annotation

GitHub Actions / Markdown to Word Converter

standard/classes.md#L3

MDC032::Line length 88 > maximum 81

A class is a data structure that may contain data members (constants and fields), function members (methods, properties, events, indexers, operators, instance constructors, finalizers, and static constructors), and nested types. Class types support inheritance, a mechanism whereby a ***derived class*** can extend and specialize a ***base class***.

Check warning on line 6 in standard/classes.md

View workflow job for this annotation

GitHub Actions / Markdown to Word Converter

standard/classes.md#L6

MDC032::Line length 83 > maximum 81
Structs ([§16](structs.md#16-structs)) and interfaces ([§19](interfaces.md#19-interfaces)) have members similar to classes but with certain restrictions. This clause defines the declarations for classes and class members. The clauses for structs and interfaces define the restrictions for those types in terms of the corresponding declarations in class types.

## 15.2 Class declarations

Check warning on line 9 in standard/classes.md

View workflow job for this annotation

GitHub Actions / Markdown to Word Converter

standard/classes.md#L9

MDC032::Line length 97 > maximum 81

Check warning on line 10 in standard/classes.md

View workflow job for this annotation

GitHub Actions / Markdown to Word Converter

standard/classes.md#L10

MDC032::Line length 83 > maximum 81
### 15.2.1 General

Check warning on line 12 in standard/classes.md

View workflow job for this annotation

GitHub Actions / Markdown to Word Converter

standard/classes.md#L12

MDC032::Line length 87 > maximum 81
A *class_declaration* is a *type_declaration* ([§14.8](namespaces.md#148-type-declarations)) that declares a new class.

```ANTLR
class_declaration

Check warning on line 16 in standard/classes.md

View workflow job for this annotation

GitHub Actions / Markdown to Word Converter

standard/classes.md#L16

MDC032::Line length 86 > maximum 81
: non_record_class_declaration
| record_class_declaration

Check warning on line 18 in standard/classes.md

View workflow job for this annotation

GitHub Actions / Markdown to Word Converter

standard/classes.md#L18

MDC032::Line length 84 > maximum 81
;

Check warning on line 20 in standard/classes.md

View workflow job for this annotation

GitHub Actions / Markdown to Word Converter

standard/classes.md#L20

MDC032::Line length 82 > maximum 81
non_record_class_declaration

Check warning on line 21 in standard/classes.md

View workflow job for this annotation

GitHub Actions / Markdown to Word Converter

standard/classes.md#L21

MDC032::Line length 93 > maximum 81
: attributes? class_modifier* 'partial'? 'class' identifier
type_parameter_list? class_base? type_parameter_constraints_clause*
class_body
Expand All @@ -27,7 +27,7 @@

There are two kinds of class: ***non-record class***, as declared by *non_record_class_declaration*, and ***record class***, as declared by *record_class_declaration*. A non-record class is the kind of class that C# has supported since the language’s inception. Record classes were added much later and are discussed in [§15.16](classes.md#1516-record-classes). The differences between the two kinds are discussed in [§15.17](classes.md#1517-record-class-and-non-record-class-differences).

A *non_record_class_declaration* consists of an optional set of *attributes* ([§23](attributes.md#23-attributes)), followed by an optional set of *class_modifier*s ([§15.2.2](classes.md#1522-class-modifiers)), followed by an optional `partial` modifier ([§15.2.7](classes.md#1527-partial-type-declarations)), followed by the keyword `class` and an *identifier* that names the class, followed by an optional *type_parameter_list* ([§15.2.3](classes.md#1523-type-parameters)), followed by an optional *class_base* specification ([§15.2.4](classes.md#1524-class-base-specification)), followed by an optional set of *type_parameter_constraints_clause*s ([§15.2.5](classes.md#1525-type-parameter-constraints)), followed by a *class_body* ([§15.2.6](classes.md#1526-class-body)).

Check warning on line 30 in standard/classes.md

View workflow job for this annotation

GitHub Actions / Markdown to Word Converter

standard/classes.md#L30

MDC032::Line length 82 > maximum 81

A class declaration shall not supply *type_parameter_constraints_clause*s unless it also supplies a *type_parameter_list*.

Expand All @@ -37,11 +37,11 @@

#### 15.2.2.1 General

A *class_declaration* may optionally include a sequence of class modifiers:

Check warning on line 40 in standard/classes.md

View workflow job for this annotation

GitHub Actions / Markdown to Word Converter

standard/classes.md#L40

MDC032::Line length 86 > maximum 81

```ANTLR
class_modifier
: 'new'

Check warning on line 44 in standard/classes.md

View workflow job for this annotation

GitHub Actions / Markdown to Word Converter

standard/classes.md#L44

MDC032::Line length 86 > maximum 81
| 'public'
| 'protected'
| 'internal'
Expand Down Expand Up @@ -2167,9 +2167,9 @@

> *Note*: The overlapping of, and priority between, alternatives here is solely for descriptive convenience; the grammar rules could be elaborated to remove the overlap. ANTLR, and other grammar systems, adopt the same convenience and so *method_body* has the specified semantics automatically. *end note*

A *method_declaration* may include a set of *attributes* ([§23](attributes.md#23-attributes)) and one of the permitted kinds of declared accessibility ([§15.3.6](classes.md#1536-access-modifiers)), the `new` ([§15.3.5](classes.md#1535-the-new-modifier)), `static` ([§15.6.3](classes.md#1563-static-and-instance-methods)), `virtual` ([§15.6.4](classes.md#1564-virtual-methods)), `override` ([§15.6.5](classes.md#1565-override-methods)), `sealed` ([§15.6.6](classes.md#1566-sealed-methods)), `abstract` ([§15.6.7](classes.md#1567-abstract-methods)), `extern` ([§15.6.8](classes.md#1568-external-methods)) and `async` ([§15.14](classes.md#1514-async-functions)). Additionally a *method_declaration* that is contained directly by a *struct_declaration* may include the `readonly` modifier ([§16.6.12](structs.md#16612-methods)).
A *method_declaration* may include a set of *attributes* ([§23](attributes.md#23-attributes)) and one of the permitted kinds of declared accessibility ([§15.3.6](classes.md#1536-access-modifiers)), the `new` ([§15.3.5](classes.md#1535-the-new-modifier)), `static` ([§15.6.3](classes.md#1563-static-and-instance-methods)), `virtual` ([§15.6.4](classes.md#1564-virtual-methods)), `override` ([§15.6.5](classes.md#1565-override-methods)), `sealed` ([§15.6.6](classes.md#1566-sealed-methods)), `abstract` ([§15.6.7](classes.md#1567-abstract-methods)), `extern` ([§15.6.8](classes.md#1568-external-methods)) and `async` ([§15.14](classes.md#1514-async-functions)) modifiers. Additionally a *method_declaration* that is contained directly by a *struct_declaration* may include the `readonly` modifier ([§16.6.12](structs.md#16612-methods)).

A declaration has a valid combination of modifiers if all of the following are true:
A *method_declaration* has a valid combination of modifiers if all of the following are true. (These rules are modified slightly in the context of an interface; see [§19.4.1](interfaces.md#1941-general).):

- The declaration includes a valid combination of access modifiers ([§15.3.6](classes.md#1536-access-modifiers)).
- The declaration does not include the same modifier multiple times.
Expand Down Expand Up @@ -4939,6 +4939,9 @@
: 'public'
| 'static'
| 'extern'
| 'abstract'
| 'virtual'
| 'sealed'
| unsafe_modifier // unsafe code support
;

Expand Down Expand Up @@ -4990,7 +4993,7 @@

The *operator_body* is either a semicolon, a block body ([§15.6.1](classes.md#1561-general)) or an expression body ([§15.6.1](classes.md#1561-general)). A block body consists of a *block*, which specifies the statements to execute when the operator is invoked. The *block* shall conform to the rules for value-returning methods described in [§15.6.11](classes.md#15611-method-body). An expression body consists of `=>` followed by an expression and a semicolon, and denotes a single expression to perform when the operator is invoked.

For `extern` operators, the *operator_body* consists simply of a semicolon. For all other operators, the *operator_body* is either a block body or an expression body.
For `extern` operators, the *operator_body* consists simply of a semicolon. For an abstract operator declaration in an interface ([§19.4.7](interfaces.md#1947-interface-operators)), the *operator_body* is a semicolon. For all other operators, the *operator_body* is either a block body or an expression body.

The following rules apply to all operator declarations:

Expand Down
21 changes: 16 additions & 5 deletions standard/conversions.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
> ```csharp
> enum Color { Red, Blue, Green }
>
> // The expression 0 converts implicitly to enum types

Check warning on line 28 in standard/conversions.md

View workflow job for this annotation

GitHub Actions / Markdown to Word Converter

standard/conversions.md#L28

MDC032::Line length 82 > maximum 81
> Color c0 = 0;
>
> // Other int expressions need explicit conversion
Expand Down Expand Up @@ -760,9 +760,14 @@
- If `E` has a type, let `S` be that type.
- If `S` or `T` are nullable value types, let `Sᵢ` and `Tᵢ` be their underlying types, otherwise let `Sᵢ` and `Tᵢ` be `S` and `T`, respectively.
- If `Sᵢ` or `Tᵢ` are type parameters, let `S₀` and `T₀` be their effective base classes, otherwise let `S₀` and `T₀` be `Sᵢ` and `Tᵢ`, respectively.
- Find the set of types, `D`, from which user-defined conversion operators will be considered. This set consists of `S₀` (if `S₀` exists and is a class or struct), the base classes of `S₀` (if `S₀` exists and is a class), and `T₀` (if `T₀` is a class or struct). A type is added to the set `D` only if an identity conversion to another type already included in the set does not exist.

- Find the set of applicable user-defined and lifted conversion operators, `U`. This set consists of the user-defined and lifted implicit conversion operators declared by the classes or structs in `D` that convert from a type encompassing `E` to a type encompassed by `T`. If `U` is empty, the conversion is undefined and a compile-time error occurs.
- Find the set of applicable user-defined and lifted conversion operators, `U`.
- Find the set of types, `D₁`, from which user-defined conversion operators will be considered. This set consists of `S₀` (if `S₀` is a class or struct), the base classes of `S₀` (if `S₀` is a class), and `T₀` (if `T₀` is a class or struct).
- Find the set of applicable user-defined and lifted conversion operators, `U₁`. This set consists of the user-defined and lifted implicit conversion operators declared by the classes or structs in `D₁` that convert from a type encompassing `S` to a type encompassed by `T`.
- If `U₁` is not empty, then `U` is `U₁`. Otherwise,
- Find the set of types, `D₂`, from which user-defined conversion operators will be considered. This set consists of `Sᵢ` *effective interface set* and their base interfaces (if `Sᵢ` is a type parameter), and `Tᵢ` *effective interface set* (if `Tᵢ` is a type parameter).
- Find the set of applicable user-defined and lifted conversion operators, `U₂`. This set consists of the user-defined and lifted implicit conversion operators declared by the interfaces in `D₂` that convert from a type encompassing `S` to a type encompassed by `T`.
- If `U₂` is not empty, then `U` is `U₂`.
- If `U` is empty, the conversion is undefined and a compile-time error occurs.
- Find the most-specific source type, `Sₓ`, of the operators in `U`:
- If `S` exists and any of the operators in `U` convert from `S`, then `Sₓ` is `S`.
- Otherwise, `Sₓ` is the most-encompassed type in the combined set of source types of the operators in `U`. If exactly one most-encompassed type cannot be found, then the conversion is ambiguous and a compile-time error occurs.
Expand All @@ -788,8 +793,14 @@
- If `E` has a type, let `S` be that type.
- If `S` or `T` are nullable value types, let `Sᵢ` and `Tᵢ` be their underlying types, otherwise let `Sᵢ` and `Tᵢ` be `S` and `T`, respectively.
- If `Sᵢ` or `Tᵢ` are type parameters, let `S₀` and `T₀` be their effective base classes, otherwise let `S₀` and `T₀` be `Sᵢ` and `Tᵢ`, respectively.
- Find the set of types, `D`, from which user-defined conversion operators will be considered. This set consists of `S₀` (if `S₀` exists and is a class or struct), the base classes of `S₀` (if `S₀` exists and is a class), `T₀` (if `T₀` is a class or struct), and the base classes of `T₀` (if `T₀` is a class). A type is added to the set `D` only if an identity conversion to another type already included in the set does not exist.
- Find the set of applicable user-defined and lifted conversion operators, `U`. This set consists of the user-defined and lifted implicit or explicit conversion operators declared by the classes or structs in `D` that convert from a type encompassing `E` or encompassed by `S` (if it exists) to a type encompassing or encompassed by `T`. If `U` is empty, the conversion is undefined and a compile-time error occurs.
- Find the set of applicable user-defined and lifted conversion operators, `U`.
- Find the set of types, `D₁`, from which user-defined conversion operators will be considered. This set consists of `S₀` (if `S₀` is a class or struct), the base classes of `S₀` (if `S₀` is a class), `T₀` (if `T₀` is a class or struct), and the base classes of `T₀` (if `T₀` is a class).
- Find the set of applicable user-defined and lifted conversion operators, `U₁`. This set consists of the user-defined and lifted implicit or explicit conversion operators declared by the classes or structs in `D₁` that convert from a type encompassing or encompassed by `S` to a type encompassing or encompassed by `T`.
- If `U₁` is not empty, then `U` is `U₁`. Otherwise,
- Find the set of types, `D₂`, from which user-defined conversion operators will be considered. This set consists of `Sᵢ` *effective interface set* and their base interfaces (if `Sᵢ` is a type parameter), and `Tᵢ` *effective interface set* and their base interfaces (if `Tᵢ` is a type parameter).
- Find the set of applicable user-defined and lifted conversion operators, `U₂`. This set consists of the user-defined and lifted implicit or explicit conversion operators declared by the interfaces in `D₂` that convert from a type encompassing or encompassed by `S` to a type encompassing or encompassed by `T`.
- If `U₂` is not empty, then `U` is `U₂`.
- If `U` is empty, the conversion is undefined and a compile-time error occurs.
- Find the most-specific source type, `Sₓ`, of the operators in `U`:
- If `S` exists and any of the operators in `U` convert from `S`, then `Sₓ` is `S`.
- Otherwise, if any of the operators in `U` convert from types that encompass `E`, then `Sₓ` is the most-encompassed type in the combined set of source types of those operators. If no most-encompassed type can be found, then the conversion is ambiguous and a compile-time error occurs.
Expand Down
Loading
Loading