По всем вопросам- @notxxx1
Реестр РКН: https://clck.ru/3Fk3kb
#VRHSZ
Post #1798
3.33K
C# вопрос с собеседований: скомпилируется ли этот код?
На первый взгляд строка выглядит криво:
Поле
Значит ли это, что доступ к нему разрешён только через
Нет.
Код скомпилируется.
В C# модификатор
То есть любой код внутри класса
Пример:
Здесь
Это часто путают на собеседованиях:
В примере это используется в static factory method:
Метод
Более интересный вопрос тут даже не в компиляции, а в дизайне.
Такой подход часто встречается в DDD:
* private constructor
* static factory method
* закрытая коллекция
* наружу отдаётся
* изменение состояния контролируется внутри агрегата
Но есть нюанс.
Ещё важнее: фабрика должна не просто копировать items, а проверять инварианты:
Иначе получается не DDD entity, а просто объект с красивой фабрикой.
Да, код компилируется.
Потому что
А хороший senior-вопрос здесь такой:
скомпилируется ли код - это база.
А вот защищает ли этот
На первый взгляд строка выглядит криво:
order._items.AddRange(items);
Поле
_items объявлено как private.Значит ли это, что доступ к нему разрешён только через
this._items?Нет.
Код скомпилируется.
В C# модификатор
private ограничивает доступ типом, а не конкретным экземпляром объекта.То есть любой код внутри класса
Order может обращаться к private-полям любого другого экземпляра Order.Пример:
public class Order
{
private readonly List<OrderItem> _items = new();
public void CopyItemsFrom(Order other)
{
_items.AddRange(other._items);
}
}
Здесь
other._items тоже валиден, потому что мы всё ещё находимся внутри типа Order.Это часто путают на собеседованиях:
private означает не «доступно только этому объекту», а «доступно только коду внутри этого класса».В примере это используется в static factory method:
var order = new Order { ... };
order._items.AddRange(items);
return order;
Метод
Create находится внутри Order, поэтому он имеет полный доступ к private-состоянию создаваемого экземпляра.Более интересный вопрос тут даже не в компиляции, а в дизайне.
Такой подход часто встречается в DDD:
* private constructor
* static factory method
* закрытая коллекция
_items* наружу отдаётся
IReadOnlyList<OrderItem>* изменение состояния контролируется внутри агрегата
Но есть нюанс.
_items.AsReadOnly() каждый раз создаёт новый wrapper. Обычно лучше кэшировать read-only view или возвращать IReadOnlyCollection<T>, если индексатор не нужен.Ещё важнее: фабрика должна не просто копировать items, а проверять инварианты:
if (items is null || items.Count == 0)
throw new DomainException("Order must contain at least one item.");
Иначе получается не DDD entity, а просто объект с красивой фабрикой.
Да, код компилируется.
Потому что
private в C# работает на уровне типа, а не экземпляра.А хороший senior-вопрос здесь такой:
скомпилируется ли код - это база.
А вот защищает ли этот
Order свои инварианты - уже архитектура.



















