Возврат нескольких значений - PullRequest
1 голос
/ 31 декабря 2008

У меня есть функция, которая определяет координаты на странице, и я возвращаю их как

Dictionary<int, Collection<Rectangle>> GetDocumentCoordinates(int DocumentId)

Однако позже мне понадобится информация о каждой странице - если она была проверена, каково разрешение страницы, цвет / ширина и т. Д. Я мог бы создать другую функцию и выполнить почти тот же набор результатов, что и предыдущая функция, и получить эта информация.

Dictionary<int, PageInfo> GetDocumentAttributes(int DocumentId)

Другой альтернативой может быть добавление параметра ref, чтобы я мог получить эти значения обратно.

Dictionary<int, Collection<Rectangle>> GetCoordinates(int DocumentId, ref Dictionary<int, PageInfo> PageAttributes)

Еще одна альтернатива - создать охватывающий класс, содержащий словарь и информацию о странице:

class DocumentInfo
{
    Dictionary<int, Collection<Rectangle>> Coordinates { get; set;}
    Dictionary<int, PageInfo> PageAttributes { get; set; }
}

и затем определите:

DocumentInfo GetDocumentInfo(int DocumentId);

Я склоняюсь к последнему варианту, но ваше понимание очень ценится.

Ответы [ 2 ]

6 голосов
/ 31 декабря 2008

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

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

Во-вторых, вы можете обнаружить, что ваши данные становятся сложными до такой степени, что вам потребуется выполнить их проверку. Вместо того, чтобы иметь эту проверку во всех методах ваших классов, где вы воздействуете на эти данные, вы можете легко обернуть это в классе данных. Единоличная ответственность и т. Д.

1 голос
/ 31 декабря 2008

Кажется, вам нужно много данных. Последний вариант должен быть хорошим и расширяемым; если вы хотите (чтобы упростить использование Dictionary<,>), вы можете инкапсулировать вещи немного больше, но тот факт, что C # напрямую не поддерживает именованные индексированные свойства, означает, что вам понадобится несколько классов, если вы просто не используете методы, подобные :

class DocumentInfo {
    Dictionary<int, Collection<Rectangle>> rectangles = ...
    public Collection<Rectangle> GetRectangles(int index) {
        return rectangles[index]; // might want to clone to
                                  // protect against mutation
    }
    Dictionary<int, PageInfo> pages = ...
    public PageInfo GetPageInfo(int index) {
        return pages[index];
    }

 }

Мне не совсем понятно, что такое int, поэтому я не могу сказать, разумно ли это (поэтому я просто оставил его в покое).

Также - при первом варианте вам, вероятно, не понадобится ref - достаточно будет использовать out.

...