I would like to write a set of c# record classes that offer both a Immutable and Mutable version of themselves.
This is similar to how there is a List and ReadOnlyList offered in c# (yes, arguably not quite as safe as the caller can still cast to the mutable version, but I am okay with that and that is not the heart of my question)
There are a few issues that I am running into in my implementations that I've tried so far:
Implement with Interfaces
public record class MutableRecord : IReadOnlyRecord
{
public int ValueTypeProperty { get; set; }
// This is is one problem. In the Mutable Record I would like to expose the Mutable
// version of the other record type. As opposed to the readonly interface.
// public OtherMutableRecord RefernceTypeProperty { get; set; }
public IReadOnlyRecord RefernceTypeProperty { get; set; }
}
public interface IReadOnlyOtherRecord
{
int SomeData { get; }
}
public record class OtherMutableRecord : IReadOnlyOtherRecord
{
public int SomeData { get; set; }
}
Implementation with Base Classes
I tried swapping out the above interfaces with base classes and then using the new keyword to achieve implementation hiding. But c# doesn't allow for multiple inheritance. In many cases I have classes which need to derive from the ReadOnlyBase class and the other base class (used for other operations in the code, such as storing common objects in a List). So ideally the interface implementation would be best, but I can't get around the interface requiring a specific type.
you can use explicit interface implementation to use expose different properties or levels of access based on the reference type:
public record class MutableRecord : IReadOnlyRecord
{
public int ValueTypeProperty { get; set; }
IReadOnlyOtherRecord IReadOnlyRecord.RefernceTypeProperty => ReferenceTypeProperty;
public OtherMutableRecord ReferenceTypeProperty { get; set;}
}
Note that "immutable" and "readonly" means slightly different things. The former implies that the object never changes, while the later that you cannot change it.