Возвращаемое значение функции из входных параметров
От: Gattaka Россия  
Дата: 21.01.17 02:50
Оценка:
Коллеги,
Как грамотно донести до людей, что если вы возвращаете значение из функции через входные параметры это не очень хорошо. В частности речь идет про шарп:
public void Foo(Some item, List<Some> correctItems, List<Some> errorItems)
{
...
}

Где correctItems и errorItems — заполняются элементами и таким образом результат работы.
Re: Возвращаемое значение функции из входных параметров
От: kaa.python Ниоткуда РСДН профессионально мёртв и завален ватой.
Дата: 21.01.17 03:06
Оценка: +1
Здравствуйте, Gattaka, Вы писали:

G>Коллеги,

G>Как грамотно донести до людей, что если вы возвращаете значение из функции через входные параметры это не очень хорошо. В частности речь идет про шарп:
  Скрытый текст
G>
G>public void Foo(Some item, List<Some> correctItems, List<Some> errorItems)
G>{
G>...
G>}
G>

G>Где correctItems и errorItems — заполняются элементами и таким образом результат работы.

Утверждение о том, что это не хорошо довольно спорное. Что брать в качестве альтернативы и чем оно лучше? Я так понимаю, в качестве правильного решения ожидается что-то следующего вида (пишу на псевдо C#, т.к. языка не знаю):
public optional<pair<List<Some>, List<Some>>> Foo(Some item)
{
...
}


Но если, к примеру, если изменить сигантуру функции следующим образом, то идея с возвращением значений таким образом уже не кажется чем-то совсем плохим:
public Code Foo(Some item, List<Some> correctItems, List<Some> errorItems)
{
...
}

С одной стороны, если что-то пошло не так можно бросить исключение, с другой стороны, может это "не так" является нормальным поведением и ошибка предпочтительнее?
Re[2]: Возвращаемое значение функции из входных параметров
От: Gattaka Россия  
Дата: 21.01.17 03:09
Оценка:
Здравствуйте, kaa.python, Вы писали:

KP>Утверждение о том, что это не хорошо довольно спорное. Что брать в качестве альтернативы и чем оно лучше? Я так понимаю, в качестве правильного решения ожидается что-то следующего вида (пишу на псевдо C#, т.к. языка не знаю):

KP>
KP>public optional<pair<List<Some>, List<Some>>> Foo(Some item)
KP>{
KP>...
KP>}
KP>


А вот и нет. В качестве правильно решения часто приходится пересматривать дизайн класса и реализуемого алгоритма. И, например, вместо одной функции появляется несколько.
Re[3]: Возвращаемое значение функции из входных параметров
От: kaa.python Ниоткуда РСДН профессионально мёртв и завален ватой.
Дата: 21.01.17 03:15
Оценка: 1 (1) +2
Здравствуйте, Gattaka, Вы писали:

G>А вот и нет. В качестве правильно решения часто приходится пересматривать дизайн класса и реализуемого алгоритма. И, например, вместо одной функции появляется несколько.


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

Я к чему веду – возвращать все данные разом можно и иногда нужно. Возможно, лучше создать дополнительный прокси-хранитель для данных и вернуть его, если такой вариант больше нравится. Но особо большого плюса в сравнении с возвратом через параметры я не вижу.
Отредактировано 21.01.2017 3:17 kaa.python . Предыдущая версия .
Re: Возвращаемое значение функции из входных параметров
От: nikov США http://www.linkedin.com/in/nikov
Дата: 21.01.17 03:20
Оценка: 1 (1) +3
Здравствуйте, Gattaka, Вы писали:

G>Коллеги,

G>Как грамотно донести до людей, что если вы возвращаете значение из функции через входные параметры это не очень хорошо. В частности речь идет про шарп:
G>
G>public void Foo(Some item, List<Some> correctItems, List<Some> errorItems)
G>{
G>...
G>}
G>


В некоторых случаях это стандартный паттерн. Например, в компиляторах нужно избегать впадания в бесконечный цикл во время байндинга имён методов при наличии циклов в иерархии наследования. Обычно для этого создаётся HashSet для хранения всех типов, которые мы посещали, и передаётся как параметр через цепочку методов, которые проверяют, не встречался ли уже текущий тип, и добавляют его в это множество. Возвращаемое значение метода, как правило, уже используется для чего-то полезного.
Re: Возвращаемое значение функции из входных параметров
От: 0x7be СССР  
Дата: 21.01.17 08:03
Оценка: 1 (1) +3
Здравствуйте, Gattaka, Вы писали:

G>Как грамотно донести до людей, что если вы возвращаете значение из функции через входные параметры это не очень хорошо. В частности речь идет про шарп:

G>...
G>Где correctItems и errorItems — заполняются элементами и таким образом результат работы.
Для начала четко сформулировать, какую проблему создаёт такой стиль.
Re: Возвращаемое значение функции из входных параметров
От: _NN_ www.nemerleweb.com
Дата: 21.01.17 08:04
Оценка: +2 -2
Здравствуйте, Gattaka, Вы писали:

G>Коллеги,

G>Как грамотно донести до людей, что если вы возвращаете значение из функции через входные параметры это не очень хорошо. В частности речь идет про шарп:

Если списки заполняются изнутри тогда почему не сказать об этом через 'out' ?
public void Foo(Some item, out List<Some> correctItems, out List<Some> errorItems)
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re: Возвращаемое значение функции из входных параметров
От: Sinix  
Дата: 21.01.17 08:44
Оценка: 4 (2) +5
Здравствуйте, Gattaka, Вы писали:

G>Где correctItems и errorItems — заполняются элементами и таким образом результат работы.


Всё зависит от того, что именно делает Foo и где он расположен.

1. Для private-методов (обход графа или элементов коллекции) подобный подход вполне нормален. Один и тот же список может заполняться из нескольких источников, и, если каждый метод будет возвращать новый экземпляр списка, то нам ещё придётся их сливать в один. Смысла в лишней работе нет.

2. Если речь про метод, который должен заполнять список целиком, то я бы предпочёл возвращать значение явно, например, как out-параметр. И возвращать не список, а IReadOnlyList (или любой другой из RO-интерфейсов).

3. Для public api я обычно предпочитаю заводить свои типы (если возвращается несколько значений) или возвращать RO-коллекции.

У тебя, как понимаю, третий вариант, поэтому я бы начал с public ItemResults Foo(Item item) и дальше смотрел, насколько хорошо оно подходит под реальный код.
Re[2]: Возвращаемое значение функции из входных параметров
От: Sharov Россия  
Дата: 21.01.17 09:45
Оценка:
Здравствуйте, _NN_, Вы писали:

_NN>Здравствуйте, Gattaka, Вы писали:


G>>Коллеги,

G>>Как грамотно донести до людей, что если вы возвращаете значение из функции через входные параметры это не очень хорошо. В частности речь идет про шарп:

_NN>Если списки заполняются изнутри тогда почему не сказать об этом через 'out' ?

_NN>
_NN>public void Foo(Some item, out List<Some> correctItems, out List<Some> errorItems)
_NN>


out или ref с ссылочными типами?
Кодом людям нужно помогать!
Re: Возвращаемое значение функции из входных параметров
От: Sharov Россия  
Дата: 21.01.17 09:47
Оценка: +1
Здравствуйте, Gattaka, Вы писали:

G>Коллеги,

G>Как грамотно донести до людей, что если вы возвращаете значение из функции через входные параметры это не очень хорошо. В частности речь идет про шарп:
G>
G>public void Foo(Some item, List<Some> correctItems, List<Some> errorItems)
G>{
G>...
G>}
G>

G>Где correctItems и errorItems — заполняются элементами и таким образом результат работы.

Можно сказать, что нарушается srp принцип и разбить на два метода.
Кодом людям нужно помогать!
Re[3]: Возвращаемое значение функции из входных параметров
От: _NN_ www.nemerleweb.com
Дата: 21.01.17 20:14
Оценка:
Здравствуйте, Sharov, Вы писали:

S>out или ref с ссылочными типами?

А что такого в них особенного ?
out T или out string ведь не смущают ?

скажем
public bool TryGetName(out string name) { ... }


class Dictionary<K,V> 
{
  public bool TryGetValue(K k, out V v) {}
}
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[4]: Возвращаемое значение функции из входных параметров
От: Sharov Россия  
Дата: 21.01.17 21:39
Оценка:
Здравствуйте, _NN_, Вы писали:

_NN>Здравствуйте, Sharov, Вы писали:


S>>out или ref с ссылочными типами?

_NN>А что такого в них особенного ?
_NN>out T или out string ведь не смущают ?

_NN>скажем

_NN>
_NN>public bool TryGetName(out string name) { ... }


_NN>class Dictionary<K,V> 
_NN>{
_NN>  public bool TryGetValue(K k, out V v) {}
_NN>}
_NN>


Можно, безусловно. Но с этими конструкциями, ссылка на ссылку, можно на грабли встать.
Кодом людям нужно помогать!
Re[5]: Возвращаемое значение функции из входных параметров
От: _NN_ www.nemerleweb.com
Дата: 22.01.17 08:35
Оценка:
Здравствуйте, Sharov, Вы писали:


S>Можно, безусловно. Но с этими конструкциями, ссылка на ссылку, можно на грабли встать.

А как вы делаете ?
Option<T> / Maybe<T>  GetValue(K k) // так ?
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[6]: Возвращаемое значение функции из входных параметров
От: Sharov Россия  
Дата: 22.01.17 10:16
Оценка:
Здравствуйте, _NN_, Вы писали:

_NN>Здравствуйте, Sharov, Вы писали:



S>>Можно, безусловно. Но с этими конструкциями, ссылка на ссылку, можно на грабли встать.

_NN>А как вы делаете ?
_NN>
_NN>Option<T> / Maybe<T>  GetValue(K k) // так ?
_NN>


Ну да, как возвращаемое значение ф-ии.
Кодом людям нужно помогать!
Re[2]: Возвращаемое значение функции из входных параметров
От: nikov США http://www.linkedin.com/in/nikov
Дата: 22.01.17 19:21
Оценка:
Здравствуйте, nikov, Вы писали:

N>В некоторых случаях это стандартный паттерн. Например, в компиляторах нужно избегать впадания в бесконечный цикл во время байндинга имён методов при наличии циклов в иерархии наследования. Обычно для этого создаётся HashSet для хранения всех типов, которые мы посещали, и передаётся как параметр через цепочку методов, которые проверяют, не встречался ли уже текущий тип, и добавляют его в это множество. Возвращаемое значение метода, как правило, уже используется для чего-то полезного.


На это можно взглянуть ещё с такой точки зрения. Довольно распространённым паттерном является передача callback-делегата в метод (или через цепочку методов), когда этот callback служит для возврата какой-то информации, второстепенной по отношению к возвращаемому значению. Причём callback может вызываться несколько раз в процессе работы метода, в то время как возвращаемое значение возвращается однократно. На передаваемую в метод коллекцию или другой объект можно смотреть на на группу callback-функций (методов этого объекта).
Re[4]: Возвращаемое значение функции из входных параметров
От: Gattaka Россия  
Дата: 23.01.17 06:11
Оценка:
Здравствуйте, kaa.python, Вы писали:


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

А вот теперь посмотрите — у вас есть данные и несколько методов по работе с ними. Напрашивается класс?
Отредактировано 23.01.2017 14:49 Gattaka . Предыдущая версия .
Re: Возвращаемое значение функции из входных параметров
От: vfedosov  
Дата: 17.02.17 11:27
Оценка:
Здравствуйте, Gattaka, Вы писали:

G>Коллеги,

G>Как грамотно донести до людей, что если вы возвращаете значение из функции через входные параметры это не очень хорошо. В частности речь идет про шарп:
G>
G>public void Foo(Some item, List<Some> correctItems, List<Some> errorItems)
G>{
G>...
G>}
G>

G>Где correctItems и errorItems — заполняются элементами и таким образом результат работы.

Твоя проблема в том, что ты сам не занешь, почему это не хорошо. Как я понимаю, просто твое чувство прекрассного почему-то это не приемлет. Но до тех пор, пока ты не привел статистически значимый юз кейз, где такой подход работает плохо, это твоя личная проблема — не стоит на коллег ее переносить. Вы с коллегами не произведение исскуства создаете, а работающий продукт. Соответственно мотивацией к выбору подходов должно быть не чуство красоты, а логика и практичность. Описанный тобой метод передачи результата работает прекрассно и за свои 15 лет работы я не сталкивался с проблемами подобного подхода.
Re: Возвращаемое значение функции из входных параметров
От: UberPsychoSvin  
Дата: 17.02.17 12:00
Оценка:
Здравствуйте, Gattaka, Вы писали:

G>Коллеги,

G>Как грамотно донести до людей, что если вы возвращаете значение из функции через входные параметры это не очень хорошо. В частности речь идет про шарп:
G>
G>public void Foo(Some item, List<Some> correctItems, List<Some> errorItems)
G>{
G>...
G>}
G>

G>Где correctItems и errorItems — заполняются элементами и таким образом результат работы.

(-) Минус в том, что подразумевается пропертя в зависимости от положения. Т.е. можно написать такую ерундень.
Foo(item, incorrect, correct)
Foo(item, correct, incorrect)
Foo(item, correct, correct)


(-) Так же минус в расширяемости, потом могут появиться almostCorrectItems, faultItems, и получится ужас.

(+) В плюcах то, что не нужно добавлять в проект специальный класс типа.
class FooResult
{
    Some      { get; }
    IsCorrect { get; }
}
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.