Recent status can be found in the comment #83803 (comment)
Edited by @tarekgh
This issue claimed the problem is not occurring on .NET 6.0 which is not true. The comment #83803 (comment) clarified that. In short, this issue is not a regression from .NET 6.0. Actually, .NET 7.0 behavior is not throwing.
End of @tarekgh edit
Edit by @tarekgh: additional case to cover when fixing
The same duplication also happens with a class (not a record) when a constructor parameter name differs only by case from a collection property, including a class that uses a params collection constructor (for example a parameter instances and a property Instances). The reflection based runtime binder fix for that case is tracked by #129760 and PR #129775. When fixing this issue in the configuration source generator, the fix should be extended to cover both the record case described above and this class case so the reflection binder and the source generator behave the same.
End of @tarekgh edit
This issue has been moved from a ticket on Developer Community.
[severity:It bothers me. A fix would be nice]
The behaviour has changed unexpectedly from how .Net 6.0 used to work.
/* Environment Variables
"MonitorConfig__Services__0__Name": "Service A"
"MonitorConfig__Services__0__Url": "http://localhost:5201/health",
"MonitorConfig__Services__1__Name": "Service B",
"MonitorConfig__Services__1__Url": "http://localhost:5202/health"
*/
/* defined Records types
public record MonitorConfig(ServiceConfig[] Services = null);
public record ServiceConfig(string Name, string Url);
*/
var builder = WebApplication.CreateBuilder(args);
builder.Configuration.AddEnvironmentVariables();
var monitorConfig = builder.Configuration.GetSection("MonitorConfig").Get();
monitorConfig will contain 4 ServiceConfig entries with duplicated instances of both ServiceA and ServceB declarations.
The expectation should be two entries as defined by the environment variables.
If I convert to use class types instead of record types, the behaviour works as expected.
The use of records should be supported and work as it did for .Net 6.0 using the same code, as I should not have to go and rewrite records to as classes after porting to .Net 7.
Original Comments
Feedback Bot on 3/8/2023, 05:37 PM:
(private comment, text removed)
Original Solutions
Chris Westermann solved on 3/9/2023, 05:05 AM, 0 votes:
I found that if I override the default constructor, then I get the behaviour I would expect
public record MonitorConfig(ServiceConfig[] Services)
{
public MonitorConfig()
: this((ServiceConfig[])null)
{ }
}
While this is a workaround, it seems odd I would need to do this since, conceptually, setting the default value of the positional parameter to null should produce the same behaviour and not cause the actual instance to have twice as many array entries as expected.
Recent status can be found in the comment #83803 (comment)
Edited by @tarekgh
This issue claimed the problem is not occurring on .NET 6.0 which is not true. The comment #83803 (comment) clarified that. In short, this issue is not a regression from .NET 6.0. Actually, .NET 7.0 behavior is not throwing.
End of @tarekgh edit
Edit by @tarekgh: additional case to cover when fixing
The same duplication also happens with a class (not a record) when a constructor parameter name differs only by case from a collection property, including a class that uses a
paramscollection constructor (for example a parameterinstancesand a propertyInstances). The reflection based runtime binder fix for that case is tracked by #129760 and PR #129775. When fixing this issue in the configuration source generator, the fix should be extended to cover both the record case described above and this class case so the reflection binder and the source generator behave the same.End of @tarekgh edit
This issue has been moved from a ticket on Developer Community.
[severity:It bothers me. A fix would be nice]
The behaviour has changed unexpectedly from how .Net 6.0 used to work.
monitorConfig will contain 4 ServiceConfig entries with duplicated instances of both ServiceA and ServceB declarations.
The expectation should be two entries as defined by the environment variables.
If I convert to use class types instead of record types, the behaviour works as expected.
The use of records should be supported and work as it did for .Net 6.0 using the same code, as I should not have to go and rewrite records to as classes after porting to .Net 7.
Original Comments
Feedback Bot on 3/8/2023, 05:37 PM:
(private comment, text removed)
Original Solutions
Chris Westermann solved on 3/9/2023, 05:05 AM, 0 votes:
I found that if I override the default constructor, then I get the behaviour I would expect
public record MonitorConfig(ServiceConfig[] Services)
{
public MonitorConfig()
: this((ServiceConfig[])null)
{ }
}
While this is a workaround, it seems odd I would need to do this since, conceptually, setting the default value of the positional parameter to null should produce the same behaviour and not cause the actual instance to have twice as many array entries as expected.