2012-04-20 2 views
2

У меня есть специальный объект, который содержит список объектов и кучу сопутствующих свойств для списка..NET C# Array Мгновуция/Передача Теория

У меня есть функция, которая вводит элементы в часть списка моего специального объекта. Функция зависит от свойств, которые сопровождают список, поэтому я решил создать новый объект, который содержит как свойства, так и список.

Вопрос 1: Кто несет ответственность за обеспечение того, чтобы список не был пустым, прежде чем функция начнет вводить предметы?

  1. Должен ли вызывающий абонент создать новый список и передать его функции?

  2. Должен ли вызывающий создать новый список и назначить его объекту независимо от состояния переданного объекта?

  3. Должна ли функция быть предназначена для захвата объекта и возврата нового списка БЕЗ модификации объекта, предоставляя вызывающему абоненту назначить возвращенный список его специальному объекту?

или ... есть ли другие варианты, которые я не рассматривал?

Связанный вопрос 2: Учитывая, что для моего проекта требуются свойства, которые сопровождают список, должен ли я выбрать новый класс, который содержит как свойства, так и список, или я должен создать созданный подкласс класса, который содержит дополнительные свойства?

+0

Я бы сказал, что это привычка, например, я всегда возвращаю новый объект. Вызывающий может просто сделать «MyObject obj = null; obj = MyFunc(); 'или даже инициализировать его прямо так: MyObject obj = MyFunc();' Если вы хотите, чтобы вызывающий объект мог изменять объект (или массив в вашем случае), вы можете вернуть экземпляр вашего объекта (или массив). В противном случае вы можете выполнить копию и вернуть новый объект (или сборку только для чтения вашего экземпляра). –

+0

Мне любопытно, что побудило вас добавить это как комментарий и не возможный ответ? Я новичок в SO, и я считаю, что не могу отметить ваш комментарий как ответ, если он действительно один (после того, как я оценил другие потенциальные ответы.) –

+0

Вы правы, но ваш вопрос не имеет права «Ответ, это больше похоже на вопрос для обсуждения. –

ответ

3

Короче говоря, объект, содержащий список отвечает, концептуальном, за то, что действительные средства для хранения данных, то есть он должен быть ответственным для создания экземпляра списка, когда это необходимо.

Если объект предназначен для представления совокупности объектов, он отвечает за поддержание того, что он фактически использует внутренне, чтобы хранить их, если только часть цели не является для нового объекта «оберткой» для нескольких типы сбора, позволяющие настраивать поведение на основе типа используемой коллекции.

Рассмотрите список. Он использует массив для хранения данных и занимается изменением размера указанного массива для хранения новых объектов, которые могут потребоваться. Вы не должны знать это о Списке; концептуально это упорядоченная, индексированная коллекция, позволяющая вставлять и удалять элементы. Это могло быть реализовано со связанным списком, или красно-черным деревом, или что-то еще; у них были бы последствия для производительности и сложности.

Обратно к случаю в пункте. Ваш объект, который должен быть списком с дополнительными свойствами, должен скрыть свою внутреннюю структуру данных. Пользователям не нужно знать, что есть список, в котором хранятся элементы. Это означает, что ваш объект должен знать, как создать свою собственную внутреннюю структуру данных и выставить методы, которые будет использоваться вызывающим пользователем для ввода новых элементов, которые действуют во внутреннем списке.

Единственное исключение - это «обертка», которая добавляет новые функции, которые могут применяться к любому из подмножеств других классов, и важно разрешить пользователю указывать класс, который новый должен «обернуть» в конкретное использование. Примером является BlockingCollection. Он добавляет возможность блокировать поток, который выполняет некоторую параллельную операцию в коллекции, пока он не будет действительным и безопасным для выполнения указанной операции (например, поток, пытающийся получить элемент из BlockingCollection, будет заблокирован, если коллекция пуста, пока другой поток не добавит что-то). При создании вы можете указать, что BlockingCollection использует определенную реализацию интерфейса IProducerConsumerCollection; скорее всего, это будет одна из встроенных коллекций «Concurrent» в том же пространстве имен, например ConcurrentBag, ConcurrentQueue или ConcurrentDictionary. Даже в этом случае существует опция «по умолчанию»; вы можете создать экземпляр объекта BlockingCollection без указания внутренней используемой параллельной структуры, и объект по умолчанию будет использовать ConcurrentQueue.

+0

Ваш ответ изменится, если я упомянул специфику: Объект, содержащий массив, представляет собой интерфейс, предназначенный для публичного API. Таким образом, я не верю, что смогу внедрить логику для интерфейса, чтобы «разглядеть собственный бизнес». –

+0

Пренебрежение моим последним комментарием. Иногда у меня могут быть серьезные мозговые пучки. В случае интерфейсов любая реализация интерфейса может и должна соответствовать тому, что вы наметили. –

2

Предполагая, что ваш список является полем/членом экземпляра вашего класса, я бы порекомендовал new в списке в конструкторе класса.

public class SpecialObject 
{ 
    List<something> myList; 
    public SpecialObject() 
    { 
     myList = new List<something>(); 
    } 
} 

Или достижения то же самое без конструктора:

public class SpecialObject 
{ 
    List<something> myList = new List<something>(); 
} 
+0

+1 избили меня. –

+0

Я тоже забыл упомянуть об этом как о возможности. Вот как я работал с массивами, и я подумал - поскольку я создаю специальный объект, который содержит массив, я поставил бы вопрос о том, кто на самом деле должен отвечать за создание экземпляра массива. –

Смежные вопросы