Skip to content

Cloning a .NET 8 record deriving from a .NET 7 record leads to loss of members #72357

@Watno

Description

@Watno

Version Used:
Compiler "4.8.0-7.24067.24 (2635711)"

Steps to Reproduce:

  1. Create a project targeting .NET 7 and define a record class
<Project Sdk="Microsoft.NET.Sdk">

    <PropertyGroup>
        <TargetFramework>net7.0</TargetFramework>
        <ImplicitUsings>enable</ImplicitUsings>
        <Nullable>enable</Nullable>
    </PropertyGroup>

</Project>
public record BaseRecord
{
    public required object Object1 { get; init; }
    public required object Object2 { get; init; }
}
  1. Create a project targeting .NET 8 and define a derived record class there
<Project Sdk="Microsoft.NET.Sdk">

    <PropertyGroup>
        <TargetFramework>net8.0</TargetFramework>
        <OutputType>Exe</OutputType>
    </PropertyGroup>

    <ItemGroup>
      <ProjectReference Include="..\DemoBase\DemoBase.csproj" />
    </ItemGroup>

</Project>
public record DerivedRecord : BaseRecord
{
}
  1. Instantiate the derived record and clone it using with
using System.Diagnostics;

var sut = new DerivedRecord
{
    Object1 = new object(),
    Object2 = new object()
};

var broken = sut with { Object2 = new object()}; 

Debug.Assert(broken.Object1 != null);

Demo.zip
https://gist.github.com/Watno/f6d78b49a15530e69a2a1cc1ce8d1e40

Expected Behavior: Members of the base record get cloned to the copy

Actual Behavior: Members of the base record disappear

Additional information: The IL code of the constructor of DerivedRecord seems to be broken:

  .method family hidebysig specialname rtspecialname instance void
    .ctor(
      class DerivedRecord original
    ) cil managed
  {
    .custom instance void [System.Runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor()
      = (01 00 00 00 )
    .custom instance void [System.Runtime]System.Diagnostics.CodeAnalysis.SetsRequiredMembersAttribute::.ctor()
      = (01 00 00 00 )
    .maxstack 8

    // [1 15 - 1 28]
    IL_0000: nop
    IL_0001: ret

  } // end of method DerivedRecord::.ctor

Metadata

Metadata

Assignees

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions