Atualmente existe uma uma alternativa mais simples e tão limpa quanto para instanciarmos um novo objeto no C#, me refiro ao object initializer.
var nota = new NotaFiscal
{
RazaoSocial = "Caelum Ensino e Inovacao",
Cnpj = "23.456.789/0001-12",
Itens = new List<ItemDaNota>
{
new("item 1", 100.0M),
new("item 2", 200.0M)
},
DataEmissao = DateTime.Now,
Observacoes = "uma obs qualquer"
};
Mas o seu uso só seria possível adicionando um construtor sem esses parâmetros.
// Me refiro a esse cara aqui!
public NotaFiscal() { }
public NotaFiscal(string razaoSocial, string cnpj, DateTime dataEmissao, IList<ItemDaNota> itens, string observacoes) {...}
E um construtor sem os parâmetros permite que o objeto de NotaFiscal possa ser inicializado sem atribuir valores aos seus campos. O que pode ser um problema do ponto de vista estrutural.
var nota = new NotaFiscal();
Então se a gente quiser passar obrigatoriamente os valores dos campos como parâmetros do construtor, acredito que a melhor alternativa seria o uso do Builder pattern.