Skip to content

Commit 28976ee

Browse files
authored
Merge pull request #558 from BillWagner/update-from-ecma-draft
Update from ecma draft
2 parents 670fc24 + 1d65049 commit 28976ee

21 files changed

+504
-379
lines changed

standard/arrays.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -82,10 +82,10 @@ Similarly, a single-dimensional array `T[]` also implements the interface `Syste
8282
> IList<string> lst5 = (IList<string>)oa1; // Exception
8383
> IList<string> lst6 = (IList<string>)oa2; // Ok
8484
>
85-
> IReadOnlyList<string> lst7 = sa; // Ok
86-
> IReadOnlyList<string> lst8 = oa1; // Error, cast needed
87-
> IReadOnlyList<object> lst9 = sa; // Ok
88-
> IReadOnlyList<object> lst10 = oa1; // Ok
85+
> IReadOnlyList<string> lst7 = sa; // Ok
86+
> IReadOnlyList<string> lst8 = oa1; // Error, cast needed
87+
> IReadOnlyList<object> lst9 = sa; // Ok
88+
> IReadOnlyList<object> lst10 = oa1; // Ok
8989
> IReadOnlyList<string> lst11 = (IReadOnlyList<string>)oa1; // Exception
9090
> IReadOnlyList<string> lst12 = (IReadOnlyList<string>)oa2; // Ok
9191
> }

standard/basic-concepts.md

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -646,7 +646,9 @@ Within the scope of a local variable, it is a compile-time error to refer to the
646646
> }
647647
> ```
648648
>
649-
> the name `A` is used in an expression context to refer to the local variable `A` and in a type context to refer to the class `A`. *end note*
649+
> the name `A` is used in an expression context to refer to the local variable `A` and in a type context to refer to the class `A`.
650+
>
651+
> *end note*
650652
651653
### 7.7.2 Name hiding
652654
@@ -968,15 +970,15 @@ The behavior of the garbage collector can be controlled, to some degree, via sta
968970
> creates an instance of class `A` and an instance of class `B`. These objects become eligible for garbage collection when the variable `b` is assigned the value `null`, since after this time it is impossible for any user-written code to access them. The output could be either
969971
>
970972
> ```console
971-
> Finalize instance of `A`
972-
> Finalize instance of `B`
973+
> Finalize instance of A
974+
> Finalize instance of B
973975
> ```
974976
>
975977
> or
976978
>
977979
> ```console
978-
> Finalize instance of `B`
979-
> Finalize instance of `A`
980+
> Finalize instance of B
981+
> Finalize instance of A
980982
> ```
981983
>
982984
> because the language imposes no constraints on the order in which objects are garbage collected.

standard/classes.md

Lines changed: 55 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,9 @@ A *class_declaration* is a *type_declaration* ([§13.7](namespaces.md#137-type-d
1212

1313
```ANTLR
1414
class_declaration
15-
: attributes? class_modifier* 'partial'? 'class' identifier type_parameter_list?
16-
class_base? type_parameter_constraints_clause* class_body ';'?
15+
: attributes? class_modifier* 'partial'? 'class' identifier
16+
type_parameter_list? class_base? type_parameter_constraints_clause*
17+
class_body ';'?
1718
;
1819
```
1920

@@ -213,9 +214,15 @@ The base class specified in a class declaration can be a constructed class type
213214
>
214215
> ```csharp
215216
> class Base<T> {}
216-
> class Extend : Base<int> // Valid, non-constructed class with constructed base class
217-
> class Extend<V> : V {} // Error, type parameter used as base class
218-
> class Extend<V> : Base<V> {} // Valid, type parameter used as type argument for base class
217+
>
218+
> // Valid, non-constructed class with constructed base class
219+
> class Extend : Base<int>
220+
>
221+
> // Error, type parameter used as base class
222+
> class Extend<V> : V {}
223+
>
224+
> // Valid, type parameter used as type argument for base class
225+
> class Extend<V> : Base<V> {}
219226
> ```
220227
>
221228
> *end example*
@@ -956,10 +963,10 @@ When a field, method, property, event, indexer, constructor, or finalizer declar
956963
> static void Main()
957964
> {
958965
> Test t = new Test();
959-
> t.x = 1; // Ok
960-
> t.y = 1; // Error, cannot access static member through instance
961-
> Test.x = 1; // Error, cannot access instance member through type
962-
> Test.y = 1; // Ok
966+
> t.x = 1; // Ok
967+
> t.y = 1; // Error, cannot access static member through instance
968+
> Test.x = 1; // Error, cannot access instance member through type
969+
> Test.y = 1; // Ok
963970
> }
964971
> }
965972
> ```
@@ -1214,10 +1221,10 @@ Every type declaration contained within a generic class declaration is implicitl
12141221
>
12151222
> static void F(T t)
12161223
> {
1217-
> Outer<T>.Inner<string>.F(t, "abc"); // These two statements have
1218-
> Inner<string>.F(t, "abc"); // the same effect
1219-
> Outer<int>.Inner<string>.F(3, "abc"); // This type is different
1220-
> Outer.Inner<string>.F(t, "abc"); // Error, Outer needs type arg
1224+
> Outer<T>.Inner<string>.F(t, "abc"); // These two statements have
1225+
> Inner<string>.F(t, "abc"); // the same effect
1226+
> Outer<int>.Inner<string>.F(3, "abc"); // This type is different
1227+
> Outer.Inner<string>.F(t, "abc"); // Error, Outer needs type arg
12211228
> }
12221229
> }
12231230
> ```
@@ -1430,9 +1437,7 @@ Constants are permitted to depend on other constants within the same program as
14301437
14311438
Constant declarations may depend on constants from other programs, but such dependencies are only possible in one direction.
14321439
1433-
> *Example*: Referring to the example above, if `A` and `B` were declared in separate programs, it would be possible for `A.X` to depend on `B.Z`, but `B.Z` could then not simultaneously depend on `A.Y`.
1434-
>
1435-
> *end example*
1440+
> *Example*: Referring to the example above, if `A` and `B` were declared in separate programs, it would be possible for `A.X` to depend on `B.Z`, but `B.Z` could then not simultaneously depend on `A.Y`. *end example*
14361441
14371442
## 14.5 Fields
14381443
@@ -1622,7 +1627,8 @@ These restrictions ensure that all threads will observe volatile writes performe
16221627
> // Run Thread2() in a new thread
16231628
> new Thread(new ThreadStart(Thread2)).Start();
16241629
>
1625-
> // Wait for Thread2() to signal that it has a result by setting finished to true.
1630+
> // Wait for Thread2() to signal that it has a result
1631+
> // by setting finished to true.
16261632
> for (;;)
16271633
> {
16281634
> if (finished)
@@ -1870,8 +1876,9 @@ method_declaration
18701876
;
18711877
18721878
method_header
1873-
: attributes? method_modifier* 'partial'? return_type member_name type_parameter_list?
1874-
'(' formal_parameter_list? ')' type_parameter_constraints_clause*
1879+
: attributes? method_modifier* 'partial'? return_type member_name
1880+
type_parameter_list? '(' formal_parameter_list? ')'
1881+
type_parameter_constraints_clause*
18751882
;
18761883
18771884
method_modifier
@@ -2179,9 +2186,7 @@ Output parameters are typically used in methods that produce multiple return val
21792186
21802187
A parameter declared with a `params` modifier is a parameter array. If a formal parameter list includes a parameter array, it shall be the last parameter in the list and it shall be of a single-dimensional array type.
21812188
2182-
> *Example*: The types `string[]` and `string[][]` can be used as the type of a parameter array, but the type `string[,]` can not.
2183-
>
2184-
> *end example*
2189+
> *Example*: The types `string[]` and `string[][]` can be used as the type of a parameter array, but the type `string[,]` can not. *end example*
21852190
21862191
It is not possible to combine the `params` modifier with the modifiers `ref` and `out`.
21872192
@@ -2243,9 +2248,14 @@ When performing overload resolution, a method with a parameter array might be ap
22432248
> using System;
22442249
> class Test
22452250
> {
2246-
> static void F(params object[] a) => Console.WriteLine("F(object[])");
2247-
> static void F() => Console.WriteLine("F()");>
2248-
> static void F(object a0, object a1) => Console.WriteLine("F(object,object)");
2251+
> static void F(params object[] a) =>
2252+
> Console.WriteLine("F(object[])");
2253+
>
2254+
> static void F() =>
2255+
> Console.WriteLine("F()");>
2256+
>
2257+
> static void F(object a0, object a1) =>
2258+
> Console.WriteLine("F(object,object)");
22492259
>
22502260
> static void Main()
22512261
> {
@@ -2505,16 +2515,16 @@ A compile-time error occurs unless all of the following are true for an override
25052515
>
25062516
> class D : C<string>
25072517
> {
2508-
> public override string F() {...} // Ok
2509-
> public override C<string> G() {...} // Ok
2510-
> public override void H(C<T> x) {...} // Error, should be C<string>
2518+
> public override string F() {...} // Ok
2519+
> public override C<string> G() {...} // Ok
2520+
> public override void H(C<T> x) {...} // Error, should be C<string>
25112521
> }
25122522
>
25132523
> class E<T,U> : C<U>
25142524
> {
2515-
> public override U F() {...} // Ok
2516-
> public override C<U> G() {...} // Ok
2517-
> public override void H(C<T> x) {...} // Error, should be C<U>
2525+
> public override U F() {...} // Ok
2526+
> public override C<U> G() {...} // Ok
2527+
> public override void H(C<T> x) {...} // Error, should be C<U>
25182528
> }
25192529
> ```
25202530
>
@@ -2977,7 +2987,7 @@ When the effective return type of a method is not `void` and the method has an e
29772987
> }
29782988
> ```
29792989
>
2980-
> the value-returning `Fmethod results in a compile-time error because control can flow off the end of the method body. The `G` and `Hmethods are correct because all possible execution paths end in a return statement that specifies a return value. The `I` method is correct, because its body is equivalent to a statement block with just a single return statement in it.
2990+
> the value-returning `Fmethod results in a compile-time error because control can flow off the end of the method body. The `G` and `Hmethods are correct because all possible execution paths end in a return statement that specifies a return value. The `I` method is correct, because its body is equivalent to a block with just a single return statement in it.
29812991
>
29822992
> *end example*
29832993
@@ -3611,7 +3621,8 @@ Events are declared using *event_declaration*s:
36113621
```ANTLR
36123622
event_declaration
36133623
: attributes? event_modifier* 'event' type variable_declarators ';'
3614-
| attributes? event_modifier* 'event' type member_name '{' event_accessor_declarations '}'
3624+
| attributes? event_modifier* 'event' type member_name
3625+
'{' event_accessor_declarations '}'
36153626
;
36163627
36173628
event_modifier
@@ -4129,7 +4140,8 @@ overloadable_unary_operator
41294140
;
41304141
41314142
binary_operator_declarator
4132-
: type 'operator' overloadable_binary_operator '(' fixed_parameter ',' fixed_parameter ')'
4143+
: type 'operator' overloadable_binary_operator
4144+
'(' fixed_parameter ',' fixed_parameter ')'
41334145
;
41344146
41354147
overloadable_binary_operator
@@ -4212,8 +4224,8 @@ The `true` and `false` unary operators require pair-wise declaration. A compile-
42124224
> {
42134225
> IntVector iv1 = new IntVector(4); // Vector of 4 x 0
42144226
> IntVector iv2;
4215-
> iv2 = iv1++; // iv2 contains 4 x 0, iv1 contains 4 x 1
4216-
> iv2 = ++iv1; // iv2 contains 4 x 2, iv1 contains 4 x 2
4227+
> iv2 = iv1++; // iv2 contains 4 x 0, iv1 contains 4 x 1
4228+
> iv2 = ++iv1; // iv2 contains 4 x 2, iv1 contains 4 x 2
42174229
> }
42184230
> }
42194231
> ```
@@ -4277,9 +4289,7 @@ For the purposes of these rules, any type parameters associated with `S` or `T
42774289
42784290
From the second rule, it follows that a conversion operator shall convert either to or from the class or struct type in which the operator is declared.
42794291
4280-
> *Example*: It is possible for a class or struct type `C` to define a conversion from `C` to `int` and from `int` to `C`, but not from `int` to `bool`.
4281-
>
4282-
> *end example*
4292+
> *Example*: It is possible for a class or struct type `C` to define a conversion from `C` to `int` and from `int` to `C`, but not from `int` to `bool`. *end example*
42834293
42844294
It is not possible to directly redefine a pre-defined conversion. Thus, conversion operators are not allowed to convert from or to `object` because implicit and explicit conversions already exist between `object` and all other types. Likewise, neither the source nor the target types of a conversion can be a base type of the other, since a conversion would then already exist. However, it *is* possible to declare operators on generic types that, for particular type arguments, specify conversions that already exist as pre-defined conversions.
42854295
@@ -4643,7 +4653,8 @@ A ***static constructor*** is a member that implements the actions required to i
46434653
46444654
```ANTLR
46454655
static_constructor_declaration
4646-
: attributes? static_constructor_modifiers identifier '(' ')' static_constructor_body
4656+
: attributes? static_constructor_modifiers identifier '(' ')'
4657+
static_constructor_body
46474658
;
46484659
46494660
static_constructor_modifiers
@@ -4802,8 +4813,10 @@ A ***finalizer*** is a member that implements the actions required to finalize a
48024813
```ANTLR
48034814
finalizer_declaration
48044815
: attributes? '~' identifier '(' ')' finalizer_body
4805-
| attributes? 'extern' unsafe_modifier? '~' identifier '(' ')' finalizer_body
4806-
| attributes? unsafe_modifier 'extern'? '~' identifier '(' ')' finalizer_body
4816+
| attributes? 'extern' unsafe_modifier? '~' identifier '(' ')'
4817+
finalizer_body
4818+
| attributes? unsafe_modifier 'extern'? '~' identifier '(' ')'
4819+
finalizer_body
48074820
;
48084821
48094822
finalizer_body

standard/conversions.md

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,18 @@ Some conversions in the language are defined from expressions to types, others f
2222
>
2323
> ```csharp
2424
> enum Color { Red, Blue, Green }
25-
> Color c0 = 0; // The expression 0 converts implicitly to enum types
26-
> Color c1 = (Color)1; // other int expressions need explicit conversion
27-
> String x = null; // Conversion from null expression (no type) to String
28-
> Func<int, int> square = x => x * x; // Conversion from lambda expression to delegate type
25+
>
26+
> // The expression 0 converts implicitly to enum types
27+
> Color c0 = 0;
28+
>
29+
> // Other int expressions need explicit conversion
30+
> Color c1 = (Color)1;
31+
>
32+
> // Conversion from null expression (no type) to String
33+
> String x = null;
34+
>
35+
> // Conversion from lambda expression to delegate type
36+
> Func<int, int> square = x => x * x;
2937
> ```
3038
>
3139
> *end example*
@@ -373,9 +381,7 @@ The explicit enumeration conversions are:
373381
374382
An explicit enumeration conversion between two types is processed by treating any participating *enum_type* as the underlying type of that *enum_type*, and then performing an implicit or explicit numeric conversion between the resulting types.
375383
376-
> *Example*: Given an *enum_type* `E` with and underlying type of `int`, a conversion from `E` to `byte` is processed as an explicit numeric conversion ([§10.3.2](conversions.md#1032-explicit-numeric-conversions)) from `int` to `byte`, and a conversion from `byte` to `E` is processed as an implicit numeric conversion ([§10.2.3](conversions.md#1023-implicit-numeric-conversions)) from `byte` to `int`.
377-
>
378-
> *end example*
384+
> *Example*: Given an *enum_type* `E` with and underlying type of `int`, a conversion from `E` to `byte` is processed as an explicit numeric conversion ([§10.3.2](conversions.md#1032-explicit-numeric-conversions)) from `int` to `byte`, and a conversion from `byte` to `E` is processed as an implicit numeric conversion ([§10.2.3](conversions.md#1023-implicit-numeric-conversions)) from `byte` to `int`. *end example*
379385
380386
### 10.3.4 Explicit nullable conversions
381387
@@ -708,9 +714,9 @@ Specifically, an anonymous function `F` is compatible with a delegate type `D`
708714
- If `F` has an explicitly typed parameter list, each parameter in `D` has the same type and modifiers as the corresponding parameter in `F`.
709715
- If `F` has an implicitly typed parameter list, `D` has no ref or out parameters.
710716
- If the body of `F` is an expression, and *either* `D` has a void return type *or* `F` is async and `D` has the return type Task, then when each parameter of `F` is given the type of the corresponding parameter in `D`, the body of `F` is a valid expression (w.r.t [§11](expressions.md#11-expressions)) that would be permitted as a *statement_expression* ([§12.7](statements.md#127-expression-statements)).
711-
- If the body of `F` is a statement block, and *either* `D` has a void return type *or* `F` is async and `D` has the return type Task, then when each parameter of `F` is given the type of the corresponding parameter in `D`, the body of `F` is a valid statement block (w.r.t [§12.3](statements.md#123-blocks)) in which no `return` statement specifies an expression.
717+
- If the body of `F` is a block, and *either* `D` has a void return type *or* `F` is async and `D` has the return type Task, then when each parameter of `F` is given the type of the corresponding parameter in `D`, the body of `F` is a valid block (w.r.t [§12.3](statements.md#123-blocks)) in which no `return` statement specifies an expression.
712718
- If the body of `F` is an expression, and *either* `F` is non-async and `D` has a non-`void` return type `T`, *or* `F` is async and `D` has a return type `Task<T>`, then when each parameter of `F` is given the type of the corresponding parameter in `D`, the body of `F` is a valid expression (w.r.t [§11](expressions.md#11-expressions)) that is implicitly convertible to `T`.
713-
- If the body of `F` is a statement block, and *either* `F` is non-async and `D` has a non-void return type `T`, *or* `F` is async and `D` has a return type `Task<T>`, then when each parameter of `F` is given the type of the corresponding parameter in `D`, the body of `F` is a valid statement block (w.r.t [§12.3](statements.md#123-blocks)) with a non-reachable end point in which each return statement specifies an expression that is implicitly convertible to `T`.
719+
- If the body of `F` is a block, and *either* `F` is non-async and `D` has a non-void return type `T`, *or* `F` is async and `D` has a return type `Task<T>`, then when each parameter of `F` is given the type of the corresponding parameter in `D`, the body of `F` is a valid block (w.r.t [§12.3](statements.md#123-blocks)) with a non-reachable end point in which each return statement specifies an expression that is implicitly convertible to `T`.
714720
715721
> *Example*: The following examples illustrate these rules:
716722
>
@@ -887,6 +893,7 @@ The compile-time application of the conversion from a method group `E` to a del
887893
> The assignment to `d4` shows how the method must be applicable in its normal form.
888894
>
889895
> The assignment to `d5` shows how parameter and return types of the delegate and method are allowed to differ only for reference types.
896+
>
890897
> *end example*
891898
892899
As with all other implicit and explicit conversions, the cast operator can be used to explicitly perform a particular conversion.

0 commit comments

Comments
 (0)