Nominal creation is just bastard serialisation

Mark
2 min readApr 1, 2021

We’ve all seen it. That guy who creates objects like…

public record Employee
{
public string Name { get; init; }
public int Age { get; init; }
public int IQ { get; init; }
}

…and initializes them like…

var employee = new Employee
{
Name = "John",
Age = 30,
IQ = 104
};

I mean, it’s great, right? It’s easy to read — we all know what every parameter is intended to represent without having to do something horrible like hover over it or use a modern IDE. And it allows for incredible usage patterns like, umm… passing the parameters in a different order! and… some sort of half-arsed duck typing! The problem is that what it also does is allow you to forget to pass in half of the parameters and fuck up any inter-parameter validation. I know this isn’t a .Net only problem, but .Net sure as fuck seems to encourage it.

You see, somewhere along the line someone is going to come along and add a new property on the entity…

public record Employee
{
public string Name { get; init; }
public int Age { get; init; }
public int IQ { get; init; }
public bool IsManager { get; init; }
}

… and you’re going to find out about all the places they forgot to change its construction at runtime. Worse still, you’re going to want to implement some sort of validation that relies on more than one property being set and your properties are going to become some clusterfuck of ugly…

public record Employee
{
public string Name { get; init; }
public int Age { get; init; }
private int? _iq
public int IQ
{
get => _iq.Value;
init
{
_iq = value;
Validate();
}
}
private bool? _isManager;
public bool IsManager
{
get => _isManager.Value;
init
{
_isManager = value;
Validate();
}
}
private void Validate()
{
if (!_iq.HasValue || !_isManager.HasValue)
return;
if (IsManager && IQ > 80)
throw new ArgumentException("Unrealistic");
}
}

…instead of clean and tight like god intended…

public record Employee(string Name, int Age, int IQ, bool IsManager)
{
public Employee(string name, int age, int iq, bool isManager)
{
if (isManager && IQ > 80)
throw new ArgumentException("Unrealistic");
(Name, Age, IQ, IsManager) = (name, age, iq, isManager);
}
}

--

--