Авто свойства и структуры - PullRequest
10 голосов
/ 17 февраля 2011

Меня интересует следующий код C #:

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; }
    }
}

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

Ответы [ 3 ]

20 голосов
/ 17 февраля 2011

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


Хотя у Стефана есть ответ, а не вопрос, у меня есть , чтобы посоветовать вам не использовать изменяемую структуру - он кусает тебя.Изменчивые структуры - это зло.

ИМО, «правильное» исправление здесь просто:

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; } }
}
15 голосов
/ 17 февраля 2011

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

struct Structure
{
    public Structure(int a, int b) : this()
    {
        PropertyA = a;
        PropertyB = b;
    }
    public int PropertyA { get; set; }
    public int PropertyB { get; set; }
}
8 голосов
/ 17 февраля 2011

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

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

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

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