Авто-свойства и структуры
Мне интересно о следующем С# -коде:
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;
}