commandline
commandline copied to clipboard
Immutable record types are not treated as immutable
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.
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.
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.