Skip to content

Commit 7807923

Browse files
RexJaeschkeBillWagner
authored andcommitted
reorg record-related text
1 parent 5a46914 commit 7807923

1 file changed

Lines changed: 13 additions & 69 deletions

File tree

standard/classes.md

Lines changed: 13 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -14,35 +14,25 @@ A *class_declaration* is a *type_declaration* ([§14.7](namespaces.md#147-type-d
1414

1515
```ANTLR
1616
class_declaration
17-
: attributes? class_modifier* 'partial'? class_tag identifier
18-
type_parameter_list? delimited_parameter_list? class_base?
19-
type_parameter_constraints_clause* class_body
17+
: non_record_class_declaration
18+
| record_class_declaration
2019
;
2120
22-
class_tag
23-
: 'class'
24-
| 'record'
21+
non_record_class_declaration
22+
: attributes? class_modifier* 'partial'? 'class' identifier
23+
type_parameter_list? class_base? type_parameter_constraints_clause*
24+
class_body ';'?
2525
;
2626
```
2727

28-
A *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 a *class_tag* 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 *delimited_parameter_list* ([§15.6.2.1]( classes.md#15621-general)), 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)), optionally followed by a semicolon.
28+
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 §rec-class. The differences between the two kinds are discussed in §rec-class-diffs.
29+
30+
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)), optionally followed by a semicolon.
2931

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

3234
A class declaration that supplies a *type_parameter_list* is a generic class declaration. Additionally, any class nested inside a generic class declaration or a generic struct declaration is itself a generic class declaration, since type arguments for the containing type shall be supplied to create a constructed type ([§8.4](types.md#84-constructed-types)).
3335

34-
If *class_tag* contains `record`, that class is a ***record class***; otherwise, it is a ***non-record class***.
35-
36-
For a record class, *class_modifier* shall not be `static`.
37-
38-
*delimited_parameter_list* shall not be present in a non-record class.
39-
40-
A *class_declaration* having a *delimited_parameter_list* declares a ***positional record class***.
41-
42-
At most only one partial type declaration of a partial record class may provide a *delimited_parameter_list*.
43-
44-
Parameters in *delimited_parameter_list* shall not have `ref`, `out` or `this` modifiers; however, `in` and `params` modifiers are permitted.
45-
4636
### 15.2.2 Class modifiers
4737

4838
#### 15.2.2.1 General
@@ -194,15 +184,13 @@ class_base
194184
| ':' class_type base_argument_list? ',' interface_type_list
195185
;
196186
197-
base_argument_list
198-
: '(' argument_list? ')'
199-
;
200-
201187
interface_type_list
202188
: interface_type (',' interface_type)*
203189
;
204190
```
205191

192+
*base_argument_list* is discussed in §rec-class-class-base-specification.
193+
206194
A record class may not inherit from a non-record class other than `object`, and a non-record class may not inherit from a record class.
207195

208196
It is an error for *class_base* to have a *base_argument_list* if the corresponding *class_declaration* does not contain a *delimited_parameter_list*.
@@ -774,15 +762,10 @@ The *class_body* of a class defines the members of that class.
774762
775763
```ANTLR
776764
class_body
777-
: '{' class_member_declaration* '}' ';'?
778-
| ';'
765+
: '{' class_member_declaration* '}'
779766
;
780767
```
781768
782-
A non-record class shall not have a *class_body* of `;`.
783-
784-
For a record class, the *class_body*s `{}`, `{};`, and `;` are equivalent. They all indicate that the only members are those synthesized by the compiler (§synth-members).
785-
786769
### 15.2.7 Partial type declarations
787770

788771
The modifier `partial` is used when defining a class, struct, or interface type in multiple parts. The `partial` modifier is a contextual keyword ([§6.4.4](lexical-structure.md#644-keywords)) and has special meaning in a *class_declaration*, a *struct_declaration*, or an *interface_declaration*. (A partial type may contain partial method declarations ([§15.6.9](classes.md#1569-partial-methods)).
@@ -849,7 +832,7 @@ The handling of attributes specified on the type or type parameters of different
849832
850833
### 15.3.1 General
851834
852-
The members of a class consist of the members introduced by its *class_member_declaration*s and the members inherited from the direct base class. For a record class, the member set also includes the synthesized members generated by the compiler (§synth-members).
835+
The members of a class consist of the members introduced by its *class_member_declaration*s and the members inherited from the direct base class.
853836
854837
```ANTLR
855838
class_member_declaration
@@ -937,10 +920,6 @@ The set of members of a type declared in multiple parts ([§15.2.7](classes.md#1
937920
938921
Field initialization order can be significant within Ccode, and some guarantees are provided, as defined in15.5.6.1](classes.md#15561-general). Otherwise, the ordering of members within a type is rarely significant, but may be significant when interfacing with other languages and environments. In these cases, the ordering of members within a type declared in multiple parts is undefined.
939922
940-
It is an error for a member of a record class to be named `Clone`.
941-
942-
It is an error for an instance field of a record class to have an unsafe type.
943-
944923
### 15.3.2 The instance type
945924
946925
Each class declaration has an associated ***instance type***. For a generic class declaration, the instance type is formed by creating a constructed type ([§8.4](types.md#84-constructed-types)) from the type declaration, with each of the supplied type arguments being the corresponding type parameter. Since the instance type uses the type parameters, it can only be used where the type parameters are in scope; that is, inside the class declaration. The instance type is the type of `this` for code written inside the class declaration. For non-generic classes, the instance type is simply the declared class.
@@ -4925,8 +4904,6 @@ Instance constructors are not inherited. Thus, a class has no instance construct
49254904

49264905
Instance constructors are invoked by *object_creation_expression*s ([§12.8.17.2](expressions.md#128172-object-creation-expressions)) and through *constructor_initializer*s.
49274906

4928-
A positional record class ([§15.2.1](classes.md#1521-general)) has a synthesized primary constructor; see §rec-class-pos-mem-pricon for more information.
4929-
49304907
### 15.11.2 Constructor initializers
49314908

49324909
All instance constructors (except those for class `object`) implicitly include an invocation of another instance constructor immediately before the *constructor_body*. The constructor to implicitly invoke is determined by the *constructor_initializer*:
@@ -5147,39 +5124,6 @@ If overload resolution is unable to determine a unique best candidate for the ba
51475124
>
51485125
> *end example*
51495126
5150-
### §copy-constructor Copy constructors
5151-
5152-
A ***copy constructor*** for a type `T` is a constructor having a single parameter of type `T`. The purpose of a copy constructor is to copy the state from the parameter to the new instance being created.
5153-
5154-
> *Example*: Consider the following:
5155-
>
5156-
> <!-- Example: {template:"standalone-lib-without-using", name:"CopyConstructors1"} -->
5157-
> ```csharp
5158-
> class Person
5159-
> {
5160-
> public int Age { get; set; }
5161-
> public string Name { get; set; }
5162-
> public Person(Person aPerson)
5163-
> {
5164-
> Name = aPerson.Name;
5165-
> Age = aPerson.Age;
5166-
> }
5167-
> }
5168-
> ````
5169-
>
5170-
> This declares a mutable, non-record class with two read-write properties, and a user-written copy constructor.
5171-
>
5172-
> In the following case,
5173-
>
5174-
> <!-- Example: {template:"standalone-lib-without-using", name:"CopyConstructors2"} -->
5175-
> ```csharp
5176-
> record Person(int Age, string Name);
5177-
> ````
5178-
>
5179-
> the record class is immutable. The synthesized auto properties `Age` and `Name` are read-init. A copy constructor is synthesized, as is a primary constructor. *end example*
5180-
5181-
In certain circumstances (§rec-class-copyclone), a copy constructor may be synthesized by the compiler, and called by synthesized code.
5182-
51835127
## 15.12 Static constructors
51845128
51855129
A ***static constructor*** is a member that implements the actions required to initialize a closed class. Static constructors are declared using *static_constructor_declaration*s:

0 commit comments

Comments
 (0)