Skip to content

Commit b3c62e0

Browse files
Nigel-Ecmajskeet
authored andcommitted
Add nullable value type cases to null conditional member & element access
1 parent 25f2f84 commit b3c62e0

File tree

1 file changed

+73
-24
lines changed

1 file changed

+73
-24
lines changed

standard/expressions.md

Lines changed: 73 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1757,23 +1757,47 @@ null_conditional_projection_initializer
17571757
;
17581758
```
17591759
1760-
A *null_conditional_member_access* expression `E` is of the form `P?.A`. Let `T` be the type of the expression `P.A`. The meaning of `E` is determined as follows:
1760+
A *null_conditional_member_access* expression `E` is of the form `P?.A`. The meaning of `E` is determined as follows:
17611761

1762-
- If `T` is a type parameter that is not known to be a reference type or a non-nullable value type, a compile-time error occurs.
1763-
- If `T` is a non-nullable value type, then the type of `E` is `T?`, and the meaning of `E` is the same as the meaning of:
1762+
- If the type of `P` is a nullable value type:
17641763

1765-
```csharp
1766-
((object)P == null) ? (T?)null : P.A
1767-
```
1764+
Let `T` be the type of `P.GetValueOrDefault().A`.
17681765

1769-
Except that `P` is evaluated only once.
1770-
- Otherwise the type of `E` is `T`, and the meaning of `E` is the same as the meaning of:
1766+
- If `T` is a type parameter that is not known to be a reference type or a non-nullable value type, a compile-time error occurs.
1767+
- If `T` is a non-nullable value type, then the type of `E` is `T?`, and the meaning of `E` is the same as the meaning of:
17711768

1772-
```csharp
1773-
((object)P == null) ? null : P.A
1774-
```
1769+
```csharp
1770+
((object)P == null) ? (T?)null : P.GetValueOrDefault().A
1771+
```
17751772

1776-
Except that `P` is evaluated only once.
1773+
Except that `P` is evaluated only once.
1774+
- Otherwise the type of `E` is `T`, and the meaning of `E` is the same as the meaning of:
1775+
1776+
```csharp
1777+
((object)P == null) ? (T)null : P.GetValueOrDefault().A
1778+
```
1779+
1780+
Except that `P` is evaluated only once.
1781+
1782+
- Otherwise:
1783+
1784+
Let `T` be the type of the expression `P.A`.
1785+
1786+
- If `T` is a type parameter that is not known to be a reference type or a non-nullable value type, a compile-time error occurs.
1787+
- If `T` is a non-nullable value type, then the type of `E` is `T?`, and the meaning of `E` is the same as the meaning of:
1788+
1789+
```csharp
1790+
((object)P == null) ? (T?)null : P.A
1791+
```
1792+
1793+
Except that `P` is evaluated only once.
1794+
- Otherwise the type of `E` is `T`, and the meaning of `E` is the same as the meaning of:
1795+
1796+
```csharp
1797+
((object)P == null) ? (T)null : P.A
1798+
```
1799+
1800+
Except that `P` is evaluated only once.
17771801

17781802
> *Note*: In an expression of the form:
17791803
>
@@ -2096,23 +2120,48 @@ null_conditional_element_access
20962120

20972121
A *null_conditional_element_access* is a conditional version of *element_access* ([§12.8.11](expressions.md#12811-element-access)) and it is a binding time error if the result type is `void`. For a null conditional expression where the result type may be `void` see ([§12.8.10](expressions.md#12810-null-conditional-invocation-expression)).
20982122

2099-
A *null_conditional_element_access* expression `E` is of the form `P?[A]B`; where `B` are the *dependent_access*es, if any. Let `T` be the type of the expression `P[A]B`. The meaning of `E` is determined as follows:
2123+
A *null_conditional_element_access* expression `E` is of the form `P?[A]B`; where `B` are the *dependent_access*es, if any. The meaning of `E` is determined as follows:
21002124

2101-
- If `T` is a type parameter that is not known to be a reference type or a non-nullable value type, a compile-time error occurs.
2102-
- If `T` is a non-nullable value type, then the type of `E` is `T?`, and the meaning of `E` is the same as the meaning of:
2125+
- If the type of `P` is a nullable value type:
21032126

2104-
```csharp
2105-
((object)P == null) ? (T?)null : P[A]B
2106-
```
2127+
Let `T` be the type of the expression `P.GetValueOrDefault()[A]B`.
2128+
2129+
- If `T` is a type parameter that is not known to be a reference type or a non-nullable value type, a compile-time error occurs.
2130+
- If `T` is a non-nullable value type, then the type of `E` is `T?`, and the meaning of `E` is the same as the meaning of:
21072131

2108-
Except that `P` is evaluated only once.
2109-
- Otherwise the type of `E` is `T`, and the meaning of `E` is the same as the meaning of:
2132+
```csharp
2133+
((object)P == null) ? (T?)null : P.GetValueOrDefault()[A]B
2134+
```
21102135

2111-
```csharp
2112-
((object)P == null) ? null : P[A]B
2113-
```
2136+
Except that `P` is evaluated only once.
2137+
- Otherwise the type of `E` is `T`, and the meaning of `E` is the same as the meaning of:
2138+
2139+
```csharp
2140+
((object)P == null) ? null : P.GetValueOrDefault()[A]B
2141+
```
2142+
2143+
Except that `P` is evaluated only once.
2144+
2145+
- Otherwise:
2146+
2147+
Let `T` be the type of the expression `P[A]B`.
2148+
2149+
- If `T` is a type parameter that is not known to be a reference type or a non-nullable value type, a compile-time error occurs.
2150+
- If `T` is a non-nullable value type, then the type of `E` is `T?`, and the meaning of `E` is the same as the meaning of:
2151+
2152+
```csharp
2153+
((object)P == null) ? (T?)null : P[A]B
2154+
```
21142155

2115-
Except that `P` is evaluated only once.
2156+
Except that `P` is evaluated only once.
2157+
- Otherwise the type of `E` is `T`, and the meaning of `E` is the same as the meaning of:
2158+
2159+
```csharp
2160+
((object)P == null) ? null : P[A]B
2161+
```
2162+
2163+
Except that `P` is evaluated only once.
2164+
21162165

21172166
> *Note*: In an expression of the form:
21182167
>

0 commit comments

Comments
 (0)