Move tuple literals from "Lexical structure" to "Expressions" (#3205)
This commit is contained in:
parent
4df9865acd
commit
5ade4ff123
|
@ -2,27 +2,11 @@
|
|||
|
||||
This proposal specifies the changes required to the [C# 6.0 (draft) Language specification](../../spec/introduction.md) to support *Tuples* as a new [value type](../../spec/types.md#value-types).
|
||||
|
||||
## Changes to [Lexical structure](../../spec/lexical-structure.md)
|
||||
## Additions to [Expressions](../../spec/expressions.md)
|
||||
|
||||
### Literals
|
||||
> Add the following section after [xxx](xxx):
|
||||
|
||||
> The grammar for [Literals](../../spec/lexical-structure.md#literals) is extended to include `tuple_literal`:
|
||||
|
||||
```antlr
|
||||
literal
|
||||
: boolean_literal
|
||||
| integer_literal
|
||||
| real_literal
|
||||
| character_literal
|
||||
| string_literal
|
||||
| null_literal
|
||||
| tuple_literal // new
|
||||
;
|
||||
```
|
||||
|
||||
> Add the following section after [The null literal](../../spec/lexical-structure.md#The-null-literal):
|
||||
|
||||
#### Tuple literals
|
||||
## Tuple literal expressions
|
||||
|
||||
A tuple literal consists of two or more tuple literal elements, each of which is optionally named.
|
||||
|
||||
|
@ -51,7 +35,7 @@ A tuple literal has a "conversion from expression" to any tuple type of the same
|
|||
|
||||
\[Example:
|
||||
```csharp
|
||||
(string name, byte age) t = (null, 5); // OK: the expressions null and 5 convert to string and byte, respectively
|
||||
(string name, byte age) t = (null, 5); // OK: null and 5 convert to string and byte, respectively
|
||||
```
|
||||
end example\]
|
||||
|
||||
|
@ -133,7 +117,7 @@ A tuple's type can be declared explicitly. Consider the following declarations:
|
|||
|
||||
The type of `pair2` is `(int, string)` with unknown element names. Similarly, the type of `pair3` is `(int, string)` but this time with the element names `code` and `message`, respectively. For `pair4` and `pair5`, one element is named, the other not.
|
||||
|
||||
In the case of `pair6`, the second element is declared as being unanmed, and any attempt to provide a name in an initializing context shall be ignored. Likewise for any attempt to change an element's name, as in the case of `pair7`.
|
||||
In the case of `pair6`, the second element is declared as being unnamed, and any attempt to provide a name in an initializing context shall be ignored. Likewise for any attempt to change an element's name, as in the case of `pair7`.
|
||||
|
||||
A tuple's type can be wholely inferred from the context in which it is used. Consider the following declarations:
|
||||
|
||||
|
@ -181,9 +165,9 @@ t1.Item2 = 3; // access the second element by its underlying name
|
|||
|
||||
System.ValueTuple<int, int> vt = t1; // identity conversion
|
||||
|
||||
var t2 = (1, 2, 3, 4, 5, 6, 7, 8, 9); // t2 is a System.ValueTuple<T1, T2, T3,..., T7, TRest>
|
||||
var t3 = t4.Rest; // t3 is a (int, int); that is, a System.ValueTuple<T1, T2>
|
||||
System.Console.WriteLine("Item9 = {0}", t1.Item9); // outputs 9 even though no such name Item9 exists!
|
||||
var t2 = (1, 2, 3, 4, 5, 6, 7, 8, 9); // t2 is a System.ValueTuple<T1, T2, T3,..., T7, TRest>
|
||||
var t3 = t4.Rest; // t3 is a (int, int); that is, a System.ValueTuple<T1, T2>
|
||||
System.Console.WriteLine("Item9 = {0}", t1.Item9); // outputs 9 even though no such name Item9 exists!
|
||||
```
|
||||
end example\]
|
||||
|
||||
|
@ -317,7 +301,7 @@ A tuple literal is implicitly typed when used in a context specifying a tuple ty
|
|||
|
||||
\[Example:
|
||||
```csharp
|
||||
(string name, byte age) t = (null, 5); // Ok: the expressions null and 5 convert to string and byte
|
||||
(string name, byte age) t = (null, 5); // OK: the expressions null and 5 convert to string and byte
|
||||
```
|
||||
end example\]
|
||||
|
||||
|
@ -391,13 +375,17 @@ Any object may be deconstructed by providing an accessible `Deconstruct` method,
|
|||
```csharp
|
||||
class Name
|
||||
{
|
||||
public void Deconstruct(out string first, out string last) { first = First; last = Last; }
|
||||
public void Deconstruct(out string first, out string last) {
|
||||
first = First; last = Last;
|
||||
}
|
||||
...
|
||||
}
|
||||
// or
|
||||
static class Extensions
|
||||
{
|
||||
public static void Deconstruct(this Name name, out string first, out string last) { first = name.First; last = name.Last; }
|
||||
public static void Deconstruct(this Name name, out string first, out string last) {
|
||||
first = name.First; last = name.Last;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
@ -469,7 +457,8 @@ The extension method `M` is a candidate method, even though the tuple `t` has di
|
|||
```csharp
|
||||
namespace System
|
||||
{
|
||||
public struct ValueTuple<[NullableAttribute(2)] T1, [NullableAttribute(2)] T2> : IStructuralComparable, IStructuralEquatable, IComparable, IComparable<(T1, T2)>, IEquatable<(T1, T2)>, ITuple
|
||||
public struct ValueTuple<[NullableAttribute(2)] T1, [NullableAttribute(2)] T2> : IStructuralComparable,
|
||||
IStructuralEquatable, IComparable, IComparable<(T1, T2)>, IEquatable<(T1, T2)>, ITuple
|
||||
{
|
||||
[NullableAttribute(1)]
|
||||
public T1 Item1;
|
||||
|
@ -489,7 +478,9 @@ namespace System
|
|||
|
||||
namespace System
|
||||
{
|
||||
public struct ValueTuple<[NullableAttribute(2)] T1, [NullableAttribute(2)] T2, [NullableAttribute(2)] T3> : IStructuralComparable, IStructuralEquatable, IComparable, IComparable<(T1, T2, T3)>, IEquatable<(T1, T2, T3)>, ITuple
|
||||
public struct ValueTuple<[NullableAttribute(2)] T1, [NullableAttribute(2)] T2, [NullableAttribute(2)] T3>
|
||||
: IStructuralComparable, IStructuralEquatable, IComparable, IComparable<(T1, T2, T3)>,
|
||||
IEquatable<(T1, T2, T3)>, ITuple
|
||||
{
|
||||
[NullableAttribute(1)]
|
||||
public T1 Item1;
|
||||
|
@ -513,7 +504,9 @@ namespace System
|
|||
{
|
||||
[NullableAttribute(0)]
|
||||
[NullableContextAttribute(1)]
|
||||
public struct ValueTuple<[NullableAttribute(2)] T1, [NullableAttribute(2)] T2, [NullableAttribute(2)] T3, [NullableAttribute(2)] T4> : IStructuralComparable, IStructuralEquatable, IComparable, IComparable<(T1, T2, T3, T4)>, IEquatable<(T1, T2, T3, T4)>, ITuple
|
||||
public struct ValueTuple<[NullableAttribute(2)] T1, [NullableAttribute(2)] T2, [NullableAttribute(2)] T3,
|
||||
[NullableAttribute(2)] T4> : IStructuralComparable, IStructuralEquatable, IComparable,
|
||||
IComparable<(T1, T2, T3, T4)>, IEquatable<(T1, T2, T3, T4)>, ITuple
|
||||
{
|
||||
public T1 Item1;
|
||||
public T2 Item2;
|
||||
|
@ -533,7 +526,9 @@ namespace System
|
|||
{
|
||||
[NullableAttribute(0)]
|
||||
[NullableContextAttribute(1)]
|
||||
public struct ValueTuple<[NullableAttribute(2)] T1, [NullableAttribute(2)] T2, [NullableAttribute(2)] T3, [NullableAttribute(2)] T4, [NullableAttribute(2)] T5> : IStructuralComparable, IStructuralEquatable, IComparable, IComparable<(T1, T2, T3, T4, T5)>, IEquatable<(T1, T2, T3, T4, T5)>, ITuple
|
||||
public struct ValueTuple<[NullableAttribute(2)] T1, [NullableAttribute(2)] T2, [NullableAttribute(2)] T3,
|
||||
[NullableAttribute(2)] T4, [NullableAttribute(2)] T5> : IStructuralComparable, IStructuralEquatable,
|
||||
IComparable, IComparable<(T1, T2, T3, T4, T5)>, IEquatable<(T1, T2, T3, T4, T5)>, ITuple
|
||||
{
|
||||
public T1 Item1;
|
||||
public T2 Item2;
|
||||
|
@ -554,7 +549,10 @@ namespace System
|
|||
{
|
||||
[NullableAttribute(0)]
|
||||
[NullableContextAttribute(1)]
|
||||
public struct ValueTuple<[NullableAttribute(2)] T1, [NullableAttribute(2)] T2, [NullableAttribute(2)] T3, [NullableAttribute(2)] T4, [NullableAttribute(2)] T5, [NullableAttribute(2)] T6> : IStructuralComparable, IStructuralEquatable, IComparable, IComparable<(T1, T2, T3, T4, T5, T6)>, IEquatable<(T1, T2, T3, T4, T5, T6)>, ITuple
|
||||
public struct ValueTuple<[NullableAttribute(2)] T1, [NullableAttribute(2)] T2, [NullableAttribute(2)] T3,
|
||||
[NullableAttribute(2)] T4, [NullableAttribute(2)] T5, [NullableAttribute(2)] T6> : IStructuralComparable,
|
||||
IStructuralEquatable, IComparable, IComparable<(T1, T2, T3, T4, T5, T6)>,
|
||||
IEquatable<(T1, T2, T3, T4, T5, T6)>, ITuple
|
||||
{
|
||||
public T1 Item1;
|
||||
public T2 Item2;
|
||||
|
@ -576,7 +574,10 @@ namespace System
|
|||
{
|
||||
[NullableAttribute(0)]
|
||||
[NullableContextAttribute(1)]
|
||||
public struct ValueTuple<[NullableAttribute(2)] T1, [NullableAttribute(2)] T2, [NullableAttribute(2)] T3, [NullableAttribute(2)] T4, [NullableAttribute(2)] T5, [NullableAttribute(2)] T6, [NullableAttribute(2)] T7> : IStructuralComparable, IStructuralEquatable, IComparable, IComparable<(T1, T2, T3, T4, T5, T6, T7)>, IEquatable<(T1, T2, T3, T4, T5, T6, T7)>, ITuple
|
||||
public struct ValueTuple<[NullableAttribute(2)] T1, [NullableAttribute(2)] T2, [NullableAttribute(2)] T3,
|
||||
[NullableAttribute(2)] T4, [NullableAttribute(2)] T5, [NullableAttribute(2)] T6, [NullableAttribute(2)] T7>
|
||||
: IStructuralComparable, IStructuralEquatable, IComparable, IComparable<(T1, T2, T3, T4, T5, T6, T7)>,
|
||||
IEquatable<(T1, T2, T3, T4, T5, T6, T7)>, ITuple
|
||||
{
|
||||
public T1 Item1;
|
||||
public T2 Item2;
|
||||
|
@ -586,10 +587,12 @@ namespace System
|
|||
public T6 Item6;
|
||||
public T7 Item7;
|
||||
public ValueTuple(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7);
|
||||
public int CompareTo([NullableAttribute(new[] { 0, 1, 1, 1, 1, 1, 1, 1 })] (T1, T2, T3, T4, T5, T6, T7) other);
|
||||
public int CompareTo([NullableAttribute(new[] { 0, 1, 1, 1, 1, 1, 1, 1 })]
|
||||
(T1, T2, T3, T4, T5, T6, T7) other);
|
||||
[NullableContextAttribute(2)]
|
||||
public override bool Equals(object? obj);
|
||||
public bool Equals([NullableAttribute(new[] { 0, 1, 1, 1, 1, 1, 1, 1 })] (T1, T2, T3, T4, T5, T6, T7) other);
|
||||
public bool Equals([NullableAttribute(new[] { 0, 1, 1, 1, 1, 1, 1, 1 })]
|
||||
(T1, T2, T3, T4, T5, T6, T7) other);
|
||||
public override int GetHashCode();
|
||||
public override string ToString();
|
||||
}
|
||||
|
@ -599,7 +602,11 @@ namespace System
|
|||
{
|
||||
[NullableAttribute(0)]
|
||||
[NullableContextAttribute(1)]
|
||||
public struct ValueTuple<[NullableAttribute(2)] T1, [NullableAttribute(2)] T2, [NullableAttribute(2)] T3, [NullableAttribute(2)] T4, [NullableAttribute(2)] T5, [NullableAttribute(2)] T6, [NullableAttribute(2)] T7, [NullableAttribute(0)] TRest> : IStructuralComparable, IStructuralEquatable, IComparable, IComparable<ValueTuple<T1, T2, T3, T4, T5, T6, T7, TRest>>, IEquatable<ValueTuple<T1, T2, T3, T4, T5, T6, T7, TRest>>, ITuple where TRest : struct
|
||||
public struct ValueTuple<[NullableAttribute(2)] T1, [NullableAttribute(2)] T2, [NullableAttribute(2)] T3,
|
||||
[NullableAttribute(2)] T4, [NullableAttribute(2)] T5, [NullableAttribute(2)] T6, [NullableAttribute(2)] T7,
|
||||
[NullableAttribute(0)] TRest> : IStructuralComparable, IStructuralEquatable, IComparable,
|
||||
IComparable<ValueTuple<T1, T2, T3, T4, T5, T6, T7, TRest>>,
|
||||
IEquatable<ValueTuple<T1, T2, T3, T4, T5, T6, T7, TRest>>, ITuple where TRest : struct
|
||||
{
|
||||
public T1 Item1;
|
||||
public T2 Item2;
|
||||
|
@ -610,11 +617,14 @@ namespace System
|
|||
public T7 Item7;
|
||||
[NullableAttribute(0)]
|
||||
public TRest Rest;
|
||||
public ValueTuple(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7, [NullableAttribute(0)] TRest rest);
|
||||
public int CompareTo([NullableAttribute(new[] { 0, 1, 1, 1, 1, 1, 1, 1, 0 })] ValueTuple<T1, T2, T3, T4, T5, T6, T7, TRest> other);
|
||||
public ValueTuple(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7,
|
||||
[NullableAttribute(0)] TRest rest);
|
||||
public int CompareTo([NullableAttribute(new[] { 0, 1, 1, 1, 1, 1, 1, 1, 0 })]
|
||||
ValueTuple<T1, T2, T3, T4, T5, T6, T7, TRest> other);
|
||||
[NullableContextAttribute(2)]
|
||||
public override bool Equals(object? obj);
|
||||
public bool Equals([NullableAttribute(new[] { 0, 1, 1, 1, 1, 1, 1, 1, 0 })] ValueTuple<T1, T2, T3, T4, T5, T6, T7, TRest> other);
|
||||
public bool Equals([NullableAttribute(new[] { 0, 1, 1, 1, 1, 1, 1, 1, 0 })]
|
||||
ValueTuple<T1, T2, T3, T4, T5, T6, T7, TRest> other);
|
||||
public override int GetHashCode();
|
||||
public override string ToString();
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue