Home > database >  Truly immutable classes for .NET Framework 4.8 and VB.NET with easy-to update constructor
Truly immutable classes for .NET Framework 4.8 and VB.NET with easy-to update constructor

Time:01-04

Because VB.NET and C# for .NET Framework (4.8) are no longer developed, new useful language features that provide immutable object functionality like records are also not available.

For a specific purpose I need to define some as-immutable-as-possible classes in a C# library for objects that are (also) used in a VB.NET Office VSTO add-in solution.

I would like to have a constructor for the immutable object that is easy to extend with extra data I'd like to get into the object.

Is the simple idea/pattern in the code below a good way to achieve this? (CIC = Constructor Input Class)

Any PersonCIC object is only used for creating the immutable object. Using a Structure as an argument for the constructor is less efficient if it becomes bigger than 16 bytes I understand from the Microsoft documentation.

The immutable objects are needed to provide simple and predictable thread safety to take advantage of multithreading. The goal is not to do proper OOP but to apply the mindset of Data-Oriented Programming as defined here. VB.NET and C# 7.x are not Clojure but they are the only options for .NET Office VSTO add-in solutions.

public sealed class PersonCIC
{
    public string name;
    public int age;
    public string address;
}

public sealed class ImmutablePerson
{
    public string name { get; }
    public int age { get; }
    public string address { get; }

    public ImmutablePerson(PersonCIC person)
    {
        name = person.name;
        age = person.age;
        address = person.address;
    }
}

CodePudding user response:

If you're not concerned about the extra allocation for the "CIC" class, your approach is reasonable and has the advantage of having the single constructor to maintain. That could in turn be advantageous if you later decide to code generate these things.

Your target class(es) are as immutable as you can get so that's good too.

I've seen strange ways of doing immutability, but they carry some baggage, and some weaknesses. Your approach doesn't have any mutability at all, which is good considering the limitations on .NET Framework and the language levels it supports.

The only drawbacks I can think of at the moment are

  • if your target and CIC classes are deeper than one level, you have to ensure the other levels are also immutable structurally as well.
  • if a default constructor is needed for serialization that could be problematic
  • Related