Home > Mobile >  Immutable value object with minimal constructor/code
Immutable value object with minimal constructor/code

Time:02-17

I need immutable instances of an object where some values are defined at runtime and some at compile time. Ideally, it looks like Car because

  1. it's immutable

  2. no constructor has to be written/updated when values get added/removed

  3. values can be grouped together no matter when they are defined and

  4. nicely readable when initializing:

    struct Car {
       public string Name { get; init; }
       public uint CountWheels { get; } = 4; 
     }
    
     Car carBrand = new() {Name = "CarBrand"}
    

The thing is, it does not work:

A 'struct' with field initializers must include an explicitly declared constructor.

How can I solve this with minimal code?

Answer to comments: any struct, record, class, etc is fine

CodePudding user response:

If your really want a struct:

public readonly record struct Car(string Name, int CountWheels)
{
    public int CountWheels { get; init; } = 4;
}

But be aware that struct are passed around by value, meaning they are copied each time you pass them around (unless you use ref). So, if you have a large struct, it might be a better idea to use a record (class), as it is passed around by reference.

And a record class without primary constructor would look like this:

public record Car
{
    public string Name { get; init; }
    public int CountWheels { get; init; } = 4;
}

You can then use the with keyword to make copies of records with some properties changed:

Car car = new() { Name = "CarBrand" };
var carCopy = car with { CountWheels = 6 };

CodePudding user response:

I think what you need is a record:

public record Car(string Name, int CountWheels = 4);

This makes it immutable, and with minimal code.

CodePudding user response:

Give it the constructor it's asking for:

struct Car {
   public string Name { get; init; }
   public uint CountWheels { get; } = 4; 
   public Car(string name) {Name = name;}
 }

 var carBrand = new Car("CarBrand");

I also agree with those suggesting this should still be a class, or maybe a record.

  • Related