Skip to content

Latest commit

 

History

History
112 lines (78 loc) · 6.34 KB

LDM-2024-05-15.md

File metadata and controls

112 lines (78 loc) · 6.34 KB

C# Language Design Meeting for May 15th, 2024

Agenda

Quote of the Day

  • "What the lowering implies here" screen goes blank "Oh, you lowered too far"

Discussion

field and value as contextual keywords

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.

Usage in nameof

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.

Conclusion

nameof(value) is legal, and will evaluate to "value". nameof(field) will not be legal.

Should value be a keyword in a property or indexer get? Should field be a keyword in an indexer?

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.

Conclusion

value will not be a keyword in property or indexer gets. 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.

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.

Conclusion

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.

Dictionary expressions

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.