With the new record type of C# 9, how is it possible to inject a custom parameter validation/ null check/ etc during the construction of the object without having to re-write the entire constructor?
Something similar to this:
record Person(Guid Id, string FirstName, string LastName, int Age)
{
override void Validate()
{
if(FirstName == null)
throw new ArgumentException("Argument cannot be null.", nameof(FirstName));
if(LastName == null)
throw new ArgumentException("Argument cannot be null.", nameof(LastName));
if(Age < 0)
throw new ArgumentException("Argument cannot be negative.", nameof(Age));
}
}
If you can live without the positional constructor, you can have your validation done in the init
portion of each property which requires it:
record Person
{
private readonly string _firstName;
private readonly string _lastName;
private readonly int _age;
public Guid Id { get; init; }
public string FirstName
{
get => _firstName;
init => _firstName = (value ?? throw new ArgumentException("Argument cannot be null.", nameof(value)));
}
public string LastName
{
get => _lastName;
init => _lastName = (value ?? throw new ArgumentException("Argument cannot be null.", nameof(value)));
}
public int Age
{
get => _age;
init =>
{
if (value < 0)
{
throw new ArgumentException("Argument cannot be negative.", nameof(value));
}
_age = value;
}
}
}
Otherwise, you will need to create a custom constructor as mentioned in a comment above.
(As an aside, consider using ArgumentNullException
and ArgumentOutOfRangeException
instead of ArgumentException
. These inherit from ArgumentException
, but are more specific as to the type of error which occurred.)
(Source)
The following achieves it too and is much shorter (and imo also clearer):
record Person (string FirstName, string LastName, int Age, Guid Id)
{
private bool _dummy = Check.StringArg(FirstName)
&& Check.StringArg(LastName) && Check.IntArg(Age);
internal static class Check
{
static internal bool StringArg(string s) {
if (s == "" || s == null)
throw new ArgumentException("Argument cannot be null or empty");
else return true;
}
static internal bool IntArg(int a) {
if (a < 0)
throw new ArgumentException("Argument cannot be negative");
else return true;
}
}
}
If only there was a way to get rid of the dummy variable.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With