Skip to content

Immutable record types are not treated as immutable #777

Open

Description

@mikhail-barg

C# 9.0 syntax allows now to declare reference types as 'records' which is a nice syntax sugar for (immutable) data-container classes. There's a way to declare a record type as 'immutable':

public sealed record MyRecord(
  string property1,
  int property2,
  object propertyEtc
)
{}

This would actually generate a following class:

public sealed class MyRecord 
{
  public string property1 {get; init;}
  public int property2 {get; init;}
  public object propertyEtc {get; init}

  public MyRecord(string property1,  int property2, object propertyEtc)
  {
     this.property1 = property1;
     this.property2 = property2;
     this.propertyEtc = propertyEtc;
  }
 //some other code, like Equals()
}

The problem is that ParseArguments<MyRecord>() would fail with System.MissingMethodException: No parameterless constructor defined for type 'MyRecord '. (which there's really none).

While I could declare a prarmeterless constructor for such record, it would be really great to have such classes supported as-is.

Activity

  1. mikhail-barg commented on Sep 23, 2021

    @mikhail-barg
    Author

    As far as I understand, the wiki on immutable types support, the class generally has all that's needed to work as an immutable, and the problem is that it is not regarded as such.

    From what I see in ReflectionExtensions.IsMutable() the culpit is this line:

      inheritedType.GetTypeInfo().GetProperties(BindingFlags.Public | BindingFlags.Instance).Any(p => p.CanWrite) ||

    which prevents init-only properties from being treated as readonly.

    See for example this post on how to detect for init properties.

  2. V0ldek commented on Jan 21, 2022

    @V0ldek

    Just ran into a related issue. I wasn't making a record class, but a regular class with all of its properties readonly, but with init. That's obviously readonly for all intents and purposes, but CommandLine throws the same System.MissingMethodException as in Mikhail's case.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions