Синтаксис C # - Ваша предпочтительная практика для получения 2 или 3 ответов от метода - PullRequest
8 голосов
/ 03 декабря 2008

Мне просто интересно, как другие разработчики решают эту проблему получения 2 или 3 ответов от метода.

1) вернуть объект []
2) вернуть пользовательский класс
3) используйте ключевое слово out или ref для нескольких переменных
4) написать или позаимствовать (F #) простой универсальный класс Tuple <>
http://slideguitarist.blogspot.com/2008/02/whats-f-tuple.html

Сейчас я работаю над кодом, который обновляет данные. Из метода, который выполняет обновление, я хотел бы передать обратно (1) время начала обновления и (2) время окончания обновления.
Позже я могу захотеть вернуть третье значение.

Мысли? Какие-нибудь хорошие практики от проектов с открытым исходным кодом .NET на эту тему?

Ответы [ 16 ]

28 голосов
/ 03 декабря 2008

Это полностью зависит от результатов. Если они связаны друг с другом, я обычно создаю собственный класс.

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

10 голосов
/ 03 декабря 2008

на двоих, обычно 4)

Более того, 2)

5 голосов
/ 03 декабря 2008

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

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

2 голосов
/ 03 декабря 2008

Лично я ненавижу параметры / ref, поэтому я бы предпочел не использовать этот подход. Кроме того, в большинстве случаев, если вам нужно вернуть более одного результата, вы, вероятно, делаете что-то не так.

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

2 голосов
/ 03 декабря 2008

Архитектура кода, я бы всегда использовал пользовательский класс, когда нужно было изменить определенное количество переменных. Зачем? Просто потому, что класс на самом деле является «планом» часто используемого типа данных, создание собственного типа данных, которым он в данном случае является, поможет вам получить хорошую структуру и помочь другим программировать для вашего интерфейса.

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

Возврат пользовательского типа, но не используйте класс, используйте структуру - отсутствие выделения памяти / сбора мусора означает отсутствие недостатков.

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

Для вашего сценария вы можете определить общий класс Range {T} (с проверками на допустимость диапазона).

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

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

Некоторые люди используют KeyValuePair для двух значений. Это не так здорово, потому что он просто помечает две вещи как Key и Value. Не очень описательно. Также было бы очень полезно добавить следующее:

public static class KeyValuePair
{
    public static KeyValuePair<K, V> Make(K k, V v) 
    { 
        return new KeyValuePair<K, V>(k, v); 
    }
}

Избавляет вас от необходимости указывать типы при его создании. Универсальные методы могут выводить типы, а универсальные конструкторы классов - нет.

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

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

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

Это зависит. Для внутреннего API, я обычно выбираю самый простой вариант. Как правило, это не так.

Для открытого API пользовательский класс обычно имеет больше смысла - но если это что-то довольно примитивное или естественным результатом функции является логическое значение (например, * .TryParse), я буду придерживаться параметра out. Вы также можете создать собственный класс с неявным приведением к bool, но обычно это просто странно.

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

...