Авто-свойства и структуры

Мне интересно о следующем С# -коде:

struct Structure
{
    public Structure(int a, int b)
    {
        PropertyA = a;
        PropertyB = b;
    }
    public int PropertyA { get; set; }
    public int PropertyB { get; set; }
}

Он не компилируется с ошибкой "Объект 'this' не может использоваться до того, как все его поля будут присвоены". Для аналогичного класса он компилируется без каких-либо проблем.

Для рефакторинга можно сделать следующее:

struct Structure
{
    private int _propertyA;
    private int _propertyB;

    public Structure(int a, int b)
    {
        _propertyA = a;
        _propertyB = b;
    }

    public int PropertyA
    {
        get { return _propertyA; }
        set { _propertyA = value; }
    }

    public int PropertyB
    {
        get { return _propertyB; }
        set { _propertyB = value; }
    }
}

Но, хотя я считаю, что цель введения авто-свойств в С# заключалась в том, чтобы избежать написания более позднего кода. Означает ли это, что авто-свойства не относятся к структурам?

Ответ 1

В С# 6 это просто исчезает; код в вопросе компилируется.


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

IMO, "правильное" исправление здесь просто:

struct Structure
{
    public Structure(int a, int b)
    {
        propertyA = a;
        propertyB = b;
    }
    private readonly int propertyA, propertyB;
    public int PropertyA { get { return propertyA; } }
    public int PropertyB { get { return propertyB; } }
}

Ответ 2

Сначала нужно вызвать конструктор по умолчанию, например:

struct Structure
{
    public Structure(int a, int b) : this()
    {
        PropertyA = a;
        PropertyB = b;
    }
    public int PropertyA { get; set; }
    public int PropertyB { get; set; }
}

Ответ 3

Как вы видели, ссылаясь на PropertyA в вашем конструкторе, вы получаете доступ к объекту this, который компилятор не разрешит, поскольку ваши поля еще не были инициализированы.

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

Другой способ заключается в том, чтобы ваш конструктор вызывал другой конструктор, который инициализирует поля. Структуры всегда неявно имеют конструктор без параметров, который инициализирует свои поля до нуля, поэтому используйте:

public Structure(int a, int b)
    : this()
{
    PropertyA = a;
    PropertyB = b;
}