Default (MyStruct) vs new MyStruct() - Qual é a diferença?

Imagem de capa Default (MyStruct) vs new MyStruct() - Qual é a diferença?

Default (MyStruct) vs new MyStruct() - Qual é a diferença?

Desde o início do .NET temos o operador default que basicamente nos dá o default do tipo dado.

Console.Write(default(int)); // Prints 0
Console.Write(default(DateTime)); // Prints 01/01/0001 00:00:00
Console.Write(default(string)); // Prints nothing as the default of every reference type is null

Para tipos de valor, mas mais específico para estruturas, você também pode fazer o mesmo com o novo operador:

Console.Write(new  int()); // Prints 0
Console.Write(new DateTime()); // Prints 01/01/0001 00:00:00

Agora nada extravagante, a menos que tragamos o C# 10 para o jogo: o C# 10 nos trouxe construtores sem parâmetros e inicializadores de campo. Então, como é a seguinte saída do console?

new MyStruct().PrintToConsole();
default(MyStruct).PrintToConsole();

public  struct MyStruct
{
      private  int anyNumber;

      public  MyStruct()
      {
          anyNumber = 10;
      }

      public void PrintToConsole() => System.Console.WriteLine($"My number is: {anyNumber}");
}

Dois "10"s em linhas separadas, não? Não. A saída correta é: 10 e 0. E a razão é simples: default não chama nenhum construtor quando se trata de estruturas. Ele não tem que fazer isso em primeiro lugar. Portanto, cada campo/propriedade também será inicializado com seus valores padrão. Você pode ver isso em ação se você estender o c'tor de nossa struct com um Console.WriteLine como este:

var a = new MyStruct();
var b = default(MyStruct);

public  struct MyStruct
{
    public MyStruct()
    {
         System.Console.Write("Hey, I was called");
    }
}

E apenas o novo MyStruct() está imprimindo algo. Portanto, esteja ciente de que o C# 10 default(MyStruct) nem sempre é o mesmo que new MyStruct().