Что здесь происходит? Как я могу вызвать конструктор по умолчанию, когда его нет?

С учетом следующего кода:

public struct Foo
{
    public Foo(int bar, int baz) : this()
    {
        Bar = bar; // Err 1, 2
        Baz = baz; // Err 3
    }

    public int Bar { get; private set; }
    public int Baz { get; private set; }
}

Что делает : this() на самом деле? Нет конструктора по умолчанию, так что он звонит? Без этого добавления все происходит с ошибками.

Error   1   The 'this' object cannot be used before all of its fields are assigned to
Error   2   Backing field for automatically implemented property 'Foo.Bar' must be fully assigned before control is returned to the caller. Consider calling the default constructor from a constructor initializer.
Error   3   Backing field for automatically implemented property 'Foo.Baz' must be fully assigned before control is returned to the caller. Consider calling the default constructor from a constructor initializer.

Ответы

Ответ 1

Итак, почему конструктор struct без аргументы не разрешены в С#? Это потому что структуры уже содержат конструктор по умолчанию, который не имеет аргументы. Имейте в виду, что это конструктор по умолчанию является частью .Net, поэтому это не видимый в нашем коде. Единственная цель конструктора по умолчанию - присваивать значения по умолчанию своим членам.

В принципе, все структуры имеют конструктор по умолчанию. Ситуация будет отличаться от класса.

Ответ 2

Когда вы используете ярлык для свойств, вы можете получить доступ к свойствам только через свои сеттеры и получатели. Однако, прежде чем все поля были назначены, вам не разрешено вызывать какие-либо сеттеры. Обходным путем для этого является вызов конструктора без параметров, который создается автоматически, который инициализирует поля. Это, конечно, означает, что вы дважды инициализируете поля.

Когда я столкнулся с этой проблемой несколько дней назад, я просто удалил ярлык для свойств и сам объявил локальные переменные, чтобы я мог установить их в конструкторе:

public struct Foo {

   public Foo(int bar, int baz) {
      _bar = bar;
      _baz = baz;
   }

   private int _bar, _baz;

   public int Bar { get { return _bar; } }
   public int Baz { get { return _baz; } }

}

Ответ 3

this обсуждает, почему они добавили эту дополнительную проверку.