field
andvalue
as contextual keywords- Usage in
nameof
- Should
value
be a keyword in a property or indexer get? Shouldfield
be a keyword in an indexer? - Should
field
andvalue
be considered keywords in lambdas and local functions within property accessors? - Should
field
andvalue
be keywords in property or accessor signatures? What aboutnameof
in those spaces?
- Usage in
- Dictionary expressions
- "What the lowering implies here" screen goes blank "Oh, you lowered too far"
Proposal: #7964
Related: #8130, #140
We started today by looking at a number of open questions in the field
and value
as contextual keywords proposal.
First up today, we considered whether field
and value
should be allowed in nameof
. nameof(value)
already works today, and there was no real pushback on keeping it
working; it has an obvious value to return (no pun intended), and is an easy way to mitigate some of the scope of the breaking change. More controversial was nameof(field)
.
First, if we do allow it, what does it evaluate to? We have precedence with type aliases; nameof(MyAliasForList)
will evaluate to the string "MyAliasForList"
, not "List"
,
but there will no doubt be at least a few users who expect it to evaluate to the actual IL name of the backing field. We're also a bit unsure about what the use case for
nameof(field)
would be in this case; it wouldn't be used for argument validation, since there is no argument. It also wouldn't be used in something like MemberNotNull
,
since it isn't accessible outside the property. We did discuss whether we should simply allow it to make field
and value
consistent, but given the lack of motivating scenarios,
we feel that it would be better to start with a tighter restriction we can loosen later if we hear feedback.
nameof(value)
is legal, and will evaluate to "value"
. nameof(field)
will not be legal.
The question at the heart of this is "should these be keywords where they will never work"? We quickly and unanimously said "no", even before finding an example of where such a change would be unnecessarily breaking.
value
will not be a keyword in property or indexer get
s. field
will not be a keyword in indexers.
Should field
and value
be considered keywords in lambdas and local functions within property accessors?
We have prior art here, both in await
inside an async
function, and in LINQ query syntax within a nested lambda. In both of those cases, the context isn't further in
interpreted; it's inside an async
method or a LINQ query, so the keywords exist. We think that these keywords should behave exactly the same way; that both simplifies the
language, and also feels like the logical conclusion.
Yes, field
and value
will be contextual keywords within nested contexts when they exist.
Should field
and value
be keywords in property or accessor signatures? What about nameof
in those spaces?
We split this question into two parts:
First, the property signature itself. Conceptually field
could be in scope here, but value
definitely wouldn't be; it isn't today, and we don't think it should be tomorrow.
For field
in this position, we don't see a reason to enable it, so it also won't be visible in the property declaration.
Second, inside accessor declarations, we have prior art of what we allow with value
today. As an example:
public class C(string s) : Attribute
{
public int P
{
get;
[param: C(nameof(value))] set;
}
}
This is existing, legal C# code, where value
is permitted in the attribute list of a property setter. Further complicating our existing rules is this example:
class value(string type) : Attribute
{
value I
{
get;
[param: value(nameof(value))] set;
}
}
In this case, the value
type shadows the parameter name, including for the nameof(value)
. This scenario is, we hope, non-existant; our search for types named value
or field
encountered nothing for the former, and only a test case in the mono/mono codebase for the latter. We therefore don't think we need to be concerned about breaking
the behavior in this case; we therefore settled on field
and value
being contextual keywords in the signatures of accessors where they exist, including in attributes.
field
is a keyword in property get
and set
accessors. value
is a keyword in property and indexer set
accessors. Neither is a keyword in the main property or indexer
signature.
Proposal: #7822 Related: KeyValuePair Correspondence
Today we looked at an outline of how KeyValuePair
(KVP
) corresponds to Tuple<T1, T2>
, and principles of how much we should let the latter shape our direction for the former.
While we didn't get down to any hard decisions today, we did have a few comments during the overview to record:
- This proposal for making
KVP
transparent doesn't address how recursive to make it. For example,KVP<string, KVP<int, int>>
. - Proposal 4, where
KVP
is fully transparent everywhere in the language, is a potential breaking change. - The meaning of adding a
KVP
changes when you consider target-typing a dictionary-like type vs a list-like type; the former will either overwrite or throw, and the latter will simply append.