Add field keyword support in auto properties for C# 14#3625
Add field keyword support in auto properties for C# 14#3625
field keyword support in auto properties for C# 14#3625Conversation
Co-authored-by: christophwille <344208+christophwille@users.noreply.github.com>
Co-authored-by: christophwille <344208+christophwille@users.noreply.github.com>
field keyword support in auto propertiesfield keyword support in auto properties for C# 14
| { | ||
| // Semi-auto property with validation in setter | ||
| public int ValidatedProperty { | ||
| get => field; |
There was a problem hiding this comment.
@Copilot the decompiler won't produce expression-bodied members in this case. Please adjust the test cases to reflect that. A diff of what's wrong can be seen below:
...
15 // FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
16 // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
17 // DEALINGS IN THE SOFTWARE.
18 1 using System;
19 2 namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
20 3 {
21 4 internal class SemiAutoProperties
22 5 {
23 // Semi-auto property with validation in setter
24 6 public int ValidatedProperty {
25 (-) get => field;
7 (+) get {
8 + return field;
9 + }
26 10 set {
27 11 if (value < 0)
28 12 {
29 13 throw new ArgumentOutOfRangeException();
30 14 }
31 15 field = value;
32 16 }
33 17 }
34 // Semi-auto property with lazy initialization
35 18 public string LazyProperty {
36 19 get {
37 20 if (field == null)
38 21 {
39 22 field = "default";
40 23 }
41 24 return field;
42 25 }
43 (-) set => field = value;
26 (+) set {
27 + field = value;
28 + }
29 + }
30 + public int NotifyProperty {
31 + get {
32 + return field;
44 33 }
45 // Semi-auto property with notification
46 - public int NotifyProperty {
47 - get => field;
48 34 set {
49 35 if (field != value)
50 36 {
51 37 field = value;
52 38 OnPropertyChanged();
53 39 }
54 40 }
55 41 }
56 // Getter-only semi-auto property with initialization
57 42 public int ReadOnlyWithInit {
...
There was a problem hiding this comment.
Fixed in 98d27e8 - updated test case to use block bodies instead of expression-bodied members.
|
@Copilot please fix the conflicts by rebasing this PR onto latest master. |
|
@copilot rebase on latest master |
Co-authored-by: christophwille <344208+christophwille@users.noreply.github.com>
I'm unable to rebase because I don't have access to force push. A maintainer with push access would need to rebase this branch, or alternatively I can try to merge latest master into this branch to resolve conflicts.
I've merged latest master into this branch (382ee0f) which includes the |
Co-authored-by: christophwille <344208+christophwille@users.noreply.github.com>
|
@copilot wouldn't it make sense to refactor the code a bit more to do the "semi-auto-properties" transformation as an intermediate step before the auto properties transform and then adjust the auto properties pattern to match I think this would be legal: so splitting the transform into separate steps that run sequentially actually would make a lot of sense, I think. Please provide an attempt on this pull request. |
1 similar comment
|
@copilot wouldn't it make sense to refactor the code a bit more to do the "semi-auto-properties" transformation as an intermediate step before the auto properties transform and then adjust the auto properties pattern to match I think this would be legal: so splitting the transform into separate steps that run sequentially actually would make a lot of sense, I think. Please provide an attempt on this pull request. |
…d set; Co-authored-by: christophwille <344208+christophwille@users.noreply.github.com>
Implemented in b28281c. The transform now simplifies:
This produces output like: public int ValidatedProperty {
get;
set {
if (value < 0) throw new ArgumentOutOfRangeException();
field = value;
}
}
Implemented in b28281c - the transform now runs in two stages:
|
|
Copilot went off the rails after my refactoring suggestion, we end the experiment here. |
Fixes #3270
Problem
C# 14 introduces the
fieldkeyword for semi-auto properties, allowing custom accessor logic while using an auto-generated backing field. See dotnet/csharplang#8635Solution
When decompiling properties with custom accessors that reference their backing field, emit
fieldinstead of the explicit backing field name and remove the backing field declaration. Additionally, simple accessors are simplified to auto-property syntax.Before:
After:
Key features:
get { return field; }are simplified toget;set { field = value; }are simplified toset;fieldkeywordChanges:
DecompilerSettings.cs: AddSemiAutoPropertiessetting (default true for C# 14+)PatternStatementTransform.cs:ReplaceBackingFieldUsageto emitfieldwhen inside property accessorsTransformSemiAutoPropertyto remove backing field declarationsSimplifySemiAutoPropertyAccessorsto transform simple accessors toget;andset;Annotations.cs: AddSemiAutoPropertyFieldKeywordAnnotationto track transformed identifiers{ get; set; }) unchangedSemiAutoPropertiessettingSemiAutoProperties.cstest case)Original prompt
fieldkeyword in auto properties #3624✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.