Как передать значение свойства только для инициализации во вложенный класс?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 должен создавать экземпляры своих колес. Замена свойств только для инициализации параметрами конструктора также крайне нежелательна. Форма публичного API Bicycle оптимальна сама по себе, я не хочу ее менять.

Обновление:< /strong>
Шинго опубликовал блестящее решение этой упрощенной проблемы, которое, к сожалению, не решает мою реальную проблему, которая немного сложнее. Класс 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#»