Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Null checking with primary constructor in C# 12

I using C# 12. In C# 12 I can use primary constructor:

public class UserService(IUnitOfWork uow) : IUserService
{
}

Before C# 12 I used null checking for items that I inject in constructor:

public class UserService : IUserService
{
    private readonly IUnitOfWork _uow;

    public UserService(IUnitOfWork uow)
    {
        ArgumentNullException.ThrowIfNull(uow);
        _uow = uow;
    }
}

Now how can I do null checking in C# 12 ?
Is it need to use fail fast with primary constructor ?

like image 701
Milad Ahmadi Avatar asked Sep 05 '25 03:09

Milad Ahmadi


2 Answers

As far as I know if you want to switch to primary constructors one of the easiest options would be to introduce field/property:

public class UserService(IUnitOfWork uow) : IUserService
{
    private readonly IUnitOfWork _uow = uow 
         ?? throw new ArgumentNullException(nameof(uow));
}

Note that you can also name the field the same as your constructor parameter (_uow -> uow), if you don't want to clutter your class with an extra name (as suggested by Heinzi) which has additional benefit of shadowing the mutable primary ctor parameter by an immutable field.

You can also encapsulate the logic into helper method. Something along these lines:

public class UserService(IUnitOfWork uow) : IUserService
{
    private readonly IUnitOfWork uow = uow.IsNotNull();
}

public static class Check
{
    [return:NotNull]
    public static T IsNotNull<T>(this T t,
         [CallerArgumentExpression("t")] string? paramName = null) where T : class
    {
        ArgumentNullException.ThrowIfNull(t, paramName);
        return t;
    }
}
like image 74
Guru Stron Avatar answered Sep 07 '25 20:09

Guru Stron


Opinionated: for this example I would omit the null check. It adds code (a liability), at the expense of clutter and distraction. I don't see the value because if uow is null things will blow up quickly in UserService tests, the cause will be obvious, and be solved (probably) by registering IUnitOfWork.

like image 24
Arthur Avatar answered Sep 07 '25 20:09

Arthur