Post

Primary constructors in C#

There are lots of thoughts on primary constructors in C#. At first they seem like a nice idea, but there are downsides.

Here are some articles, which seem to start positively but become more negative the more you look at it!

A quick refresh - this is what they look like:

1
2
3
4
5
6
7
8
public class HomeController(ILogger<HomeController> logger) : Controller
{
    public IActionResult Index()
    {
        logger.Log(LogLevel.Trace, "Index action called");
        return View();
    }
}

This shows the primary constructor being used to initialize a field. There are a few things to note about this:

  • the code could also directly access logger as well as _logger
  • logger is protected (ie it can be accessed outside this class)
  • logger is mutable (_logger is not)
  • you could just use logger and not define _logger

This already indicates some problems:

  • there’s more than one way to do it, which could lead to inconsistency
  • there are ways to do it wrongly:
    • ie use both logger and _logger
    • this gives a compiler warning, but not everyone pays attention to warnings
  • it’s easy to confuse constructor parameters with regular variables

Primary constructors were originally introduced for record types. In records the constructor parameters are immutable and public.

Conclusion:
The syntax allows for all kinds of inconsistency and confusion, so it’s up to you to address that. Probably the best recommendation is:

  • use the primary constructor parameter directly in very simple class
  • use the primary constructor parameter to initialize a class field in more complex classes

Or just don’t use primary constructors at all :shrug:

This post is licensed under CC BY 4.0 by the author.