Как передать значение свойства только для инициализации во вложенный класс?C#

Место общения программистов C#
Ответить
Anonymous
 Как передать значение свойства только для инициализации во вложенный класс?

Сообщение Anonymous »

У меня есть класс Wheel со свойством Spokes, доступным только для инициализации:

Код: Выделить всё

public class Wheel
{
internal Wheel() { }

public int Spokes { get; init; }
}
Для функциональности этого класса критически важно, чтобы спицы были неизменяемыми после создания экземпляра объекта Wheel. Поэтому крайне желательно, чтобы свойство было доступно только для инициализации и поддерживалось полем только для чтения.
Теперь у меня есть класс Bicycle, который содержит два экземпляра. класса Wheel:

Код: Выделить всё

public class Bicycle
{
private readonly Wheel _frontWheel = new();
private readonly Wheel _rearWheel = new();

public int FrontWheelSpokes
{
get => _frontWheel.Spokes;
init => _frontWheel.Spokes = value;
}

public int RearWheelSpokes
{
get => _rearWheel.Spokes;
init => _rearWheel.Spokes = value;
}
}
Предполагаемое использование этого класса:

Код: Выделить всё

Bicycle bicycle = new() { FrontWheelSpokes = 32, RearWheelSpokes = 24 };
К сожалению, этот код не компилируется. Я получаю две ошибки компиляции в строках init => _xxxWheel.Spokes = value;:

Свойство только для инициализации или индексатор 'Wheel.Spokes ' может быть назначен только в инициализаторе объекта или на 'this' или 'base' в конструкторе экземпляра или методе доступа 'init'.

Онлайн demo.
Могу ли я что-нибудь сделать, чтобы исправить ошибки компиляции, не ставя под угрозу "только инициализацию" свойств Wheel.Spokes, Bicycle.FrontWheelSpokes и Bicycle.RearWheelSpokes? Кроме того, я не хочу выставлять конструктор класса Wheel на внешнюю стену. Только сам велосипед должен создавать экземпляры своих колес.

Обновление:
Шинго опубликовал блестящее решение этой упрощенной проблемы, которое, к сожалению, не решает мою реальную проблему, которая немного сложнее. Класс Bicycle предоставляет два свойства класса Wheel, предназначенные только для инициализации, а не только Spokes. Допустим, у Колеса тоже есть это:

Код: Выделить всё

public bool DiskBrake { get; init; }
...с соответствующими свойствами в классе Bicycle:

Код: Выделить всё

public bool FrontWheelDiskBrake
{
get => _frontWheel.DiskBrake;
init => _frontWheel.DiskBrake = value;
}

public bool RearWheelDiskBrake
{
get => _rearWheel.DiskBrake;
init => _rearWheel.DiskBrake = value;
}
Желательное использование:

Код: Выделить всё

Bicycle bicycle = new()
{
FrontWheelSpokes = 32,
RearWheelSpokes = 24,
FrontWheelDiskBrake = true,
RearWheelDiskBrake = false
};
Бонусные баллы, если кто-то сможет найти решение и этой более сложной проблемы!

Подробнее здесь: https://stackoverflow.com/questions/785 ... osed-class
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C#»