[Proposal]: method attribute target for records for targeting primary constructor
- Dominant language
- C#
- Stars
- 12.7k
- Forks
- 1.1k
- Avg merge
- 11h 1m
- Merged PRs (30d)
- 3
Description
# Allow "method" as an attribute target for records and record structs for targeting the primary constructor
* [x] Proposed
* [x] Prototype: ?
* [x] Implementation: Done, implemented in released version of C# 12
* [ ] Specification: ?
## Summary
It should be possible to specify that an attribute targets the primary constructor of a record/record struct, e.g.
```cs
[method: Attr]
public record Rec(
[property: Foo] int X,
[field: NonSerialized] int Y
);
```
## Motivation
There is currently no way to add attributes to the auto generated primary constructor when declaring records. This is needed for example to add JsonConstructorAttribute to specify which constructor json serializers should use when deserializing a record type with additional constructors. (both System.Text.Json and Newtonsoft.Json has this). See also discussion at #3650
## Detailed design
The "method" attribute target should be allowed on records and record structs and would result in the generated primary constructor (but not the generated copy constructor) having that attribute. Explicitly declared constructors are unaffected.
Attributes with the `method` target are only allowed on declarations specifying the primary constructor. They are ignored with a warning when used with declarations without a parameter list:
```cs
[method: FooAttr] // Good
public partial record Rec(
[property: Foo] int X,
[field: NonSerialized] int Y
);
[method: BarAttr] // warning CS0657: 'method' is not a valid attribute location for this declaration. Valid attribute locations for this declaration are 'type'. All attributes in this block will be ignored.
public partial record Rec
{
public void Frobnicate()
{
...
}
}
[method: Attr] // Good
public record MyUnit1();
[method: Attr] // warning CS0657: 'method' is not a valid attribute location for this declaration. Valid attribute locations for this declaration are 'type'. All attributes in this block will be ignored.
public record MyUnit2;
```
## Drawbacks
Still no way to target the copy constructor. Also "method" may be a bit confusing as opposed to adding a new "constructor" target.
## Alternatives
* Add a new "constructor" attribute target with the same functionality.
* Make the attribute target both the primary and the copy constructor (this does not solve the problem with adding JsonConstructorAttribute though)
## Unresolved questions
## Design meetings
* https://github.com/dotnet/csharplang/blob/main/meetings/2023/LDM-2023-03-13.md#attributes-on-primary-ctors
Contributor guide
No contributing guide indexed for this repository
Assessment
This issue has not been assessed yet.