Используя объектно-ориентированное программирование, у нас есть возможность создать класс внутри класса (вложенный класс), но я никогда не создавал вложенный класс за 4 года своего опыта программирования.
Для чего нужны вложенные классы?
Я знаю, что класс может быть помечен как закрытый, если он вложенный, и что мы можем получить доступ ко всем закрытым членам этого класса из содержащего класса. Мы могли бы просто поместить переменные как приватные в сам содержащий класс.
Так зачем создавать вложенный класс?
В каких сценариях должны использоваться вложенные классы или они более мощные с точки зрения использования по сравнению с другими методами?
c#
object-oriented
programming-practices
.net
class-design
майур рати
источник
источник
Ответы:
Главной особенностью вложенных классов является то, что они могут получить доступ к закрытым членам внешнего класса, имея при этом всю мощь самого класса. Также они могут быть приватными, что позволяет при некоторых обстоятельствах выполнять довольно мощную инкапсуляцию:
Здесь мы полностью блокируем установщик до фабрики, так как класс является частным, ни один потребитель не может уменьшить его и получить доступ к установщику, и мы можем полностью контролировать то, что разрешено.
Помимо этого, это полезно для реализации сторонних интерфейсов в контролируемой среде, где мы все еще можем получить доступ к закрытым членам.
Если бы мы, например, предоставили экземпляр некоторого интерфейса другому объекту, но мы не хотим, чтобы наш основной класс реализовал его, мы могли бы позволить внутреннему классу реализовать его.
источник
Outer
, вы должны передатьFunc<int>
, который будет просто() => _example
Inner
не вложено иinternal
не работает (т.е. когда вы не имеете дело с различными сборками). Хит читаемости от классов вложенности делает его менее благоприятным, чем использованиеinternal
(где это возможно).Как правило, вложенный класс N создается внутри класса C всякий раз, когда C нужно использовать что-то внутренне, что никогда не должно (непосредственно) использоваться вне C, и по любой причине, что что-то должно быть объектом нового типа, а не каким-либо существующим тип.
Я считаю, что чаще всего это происходит при реализации метода, который возвращает объект, реализующий некоторый интерфейс, и мы хотим скрыть конкретный тип этого объекта, потому что он больше нигде не будет полезен.
Реализация IEnumerable является хорошим примером этого:
У кого-то за пределами просто нет причин
BlobOfBusinessData
знать или заботиться о конкретномBusinessDatumEnumerator
типе, поэтому мы могли бы оставить его внутриBlobOfBusinessData
.Это не предназначалось для того, чтобы быть примером «наилучшей практики» для
IEnumerable
правильной реализации , просто для того, чтобы донести идею до конца, поэтому я пропустил такие вещи, как явныйIEnumerable.GetEnumerator()
метод.источник
Node
класс вLinkedList
. Любой, кто используетLinkedList
, не заботится о томNode
, как он реализован, если он может получить доступ к содержимому. Единственная сущность, которая заботится вообще - этоLinkedList
сам класс.Я могу вспомнить пару важных причин:
1. Включить инкапсуляцию
Многократно вложенные классы являются деталями реализации класса. Пользователи основного класса не должны заботиться об их существовании. Вы должны иметь возможность изменять их по своему усмотрению, не требуя от пользователей основного класса изменять свой код.
2. Избегайте загрязнения имени
Не следует добавлять типы, переменные, функции и т. Д. В область, если они не подходят для этой области. Это немного отличается от инкапсуляции. Может быть полезно раскрыть интерфейс вложенного типа, но надлежащее место для вложенного типа по-прежнему остается основным классом. В земле C ++ типы итераторов являются одним из таких примеров. Я не обладаю достаточным опытом в C #, чтобы дать вам конкретные примеры.
Давайте создадим упрощенный пример, чтобы проиллюстрировать, почему перемещение вложенного класса в ту же область, что и основной класс, является загрязнением имени. Допустим, вы реализуете класс связанного списка. Обычно вы бы использовали
Если вы решите перейти
Node
на ту же областьLinkedList
, что и у вас будетLinkedListNode
вряд ли будет полезен безLinkedList
самого класса. Даже еслиLinkedList
предоставлены некоторые функции, которые возвращаютLinkedListNode
объект, которыйLinkedList
может использовать пользователь, он все равно становитсяLinkedListNode
полезным только приLinkedList
использовании. По этой причине, превращение класса «узел» в класс равноправного узлаLinkedList
загрязняет область действия.источник
Я использую публичные вложенные классы для связанных вспомогательных классов.
Используйте их для связанных вариантов.
Звонящий может выбрать, какая версия подходит для какой проблемы. Иногда класс не может быть полностью создан за один проход и требует изменяемой версии. Это всегда верно при обработке циклических данных. Изменяемые файлы могут быть преобразованы в только для чтения позже.
Я использую их для внутренних записей
источник
Вложенный класс можно использовать всякий раз, когда вы хотите создать более одного экземпляра класса или когда вы хотите сделать этот тип более доступным.
Вложенный класс увеличивает инкапсуляцию, а также приведет к более удобочитаемому и поддерживаемому коду.
источник