Короче говоря, объект, содержащий список отвечает, концептуальном, за то, что действительные средства для хранения данных, то есть он должен быть ответственным для создания экземпляра списка, когда это необходимо.
Если объект предназначен для представления совокупности объектов, он отвечает за поддержание того, что он фактически использует внутренне, чтобы хранить их, если только часть цели не является для нового объекта «оберткой» для нескольких типы сбора, позволяющие настраивать поведение на основе типа используемой коллекции.
Рассмотрите список. Он использует массив для хранения данных и занимается изменением размера указанного массива для хранения новых объектов, которые могут потребоваться. Вы не должны знать это о Списке; концептуально это упорядоченная, индексированная коллекция, позволяющая вставлять и удалять элементы. Это могло быть реализовано со связанным списком, или красно-черным деревом, или что-то еще; у них были бы последствия для производительности и сложности.
Обратно к случаю в пункте. Ваш объект, который должен быть списком с дополнительными свойствами, должен скрыть свою внутреннюю структуру данных. Пользователям не нужно знать, что есть список, в котором хранятся элементы. Это означает, что ваш объект должен знать, как создать свою собственную внутреннюю структуру данных и выставить методы, которые будет использоваться вызывающим пользователем для ввода новых элементов, которые действуют во внутреннем списке.
Единственное исключение - это «обертка», которая добавляет новые функции, которые могут применяться к любому из подмножеств других классов, и важно разрешить пользователю указывать класс, который новый должен «обернуть» в конкретное использование. Примером является BlockingCollection. Он добавляет возможность блокировать поток, который выполняет некоторую параллельную операцию в коллекции, пока он не будет действительным и безопасным для выполнения указанной операции (например, поток, пытающийся получить элемент из BlockingCollection, будет заблокирован, если коллекция пуста, пока другой поток не добавит что-то). При создании вы можете указать, что BlockingCollection использует определенную реализацию интерфейса IProducerConsumerCollection; скорее всего, это будет одна из встроенных коллекций «Concurrent» в том же пространстве имен, например ConcurrentBag, ConcurrentQueue или ConcurrentDictionary. Даже в этом случае существует опция «по умолчанию»; вы можете создать экземпляр объекта BlockingCollection без указания внутренней используемой параллельной структуры, и объект по умолчанию будет использовать ConcurrentQueue.
Я бы сказал, что это привычка, например, я всегда возвращаю новый объект. Вызывающий может просто сделать «MyObject obj = null; obj = MyFunc(); 'или даже инициализировать его прямо так: MyObject obj = MyFunc();' Если вы хотите, чтобы вызывающий объект мог изменять объект (или массив в вашем случае), вы можете вернуть экземпляр вашего объекта (или массив). В противном случае вы можете выполнить копию и вернуть новый объект (или сборку только для чтения вашего экземпляра). –
Мне любопытно, что побудило вас добавить это как комментарий и не возможный ответ? Я новичок в SO, и я считаю, что не могу отметить ваш комментарий как ответ, если он действительно один (после того, как я оценил другие потенциальные ответы.) –
Вы правы, но ваш вопрос не имеет права «Ответ, это больше похоже на вопрос для обсуждения. –