Здравствуйте, Кодёнок, Вы писали:
_FR>>Конечно. Потому что далеко не каждый Кё>>>foo(x) -> попугай _FR>>а лишь при стечении некоторых обстоятельств.
Кё>Ну будет твоя микроволновка включать гриль вместо 20 сек не всегда, а только когда в комнате темно. Суть не меняется.
Ну почему сразу гриль-то? Вот в режиме настройки времени кнопка таймера устанавливает время. Мне это не мешает готовить пищу.
Help will always be given at Hogwarts to those who ask for it.
Вообще конечно баян, о котором даже в некоторых книгах написано. Например, насколько я помню, Рихтер писал что это сделано для большей эффективности — мол не надо создавать массив и потом его garbage-collect'ить. А то что передается null, а не пустой массив — ну тут тоже, насколько я помню, в методах, принимающих массивы или коллекции, аргумент равный null принято считать за пустую коллекцию, т.е. метод должен быть готов, что ему могут передать null (в общем-то практически любой метод должен это проверять) и трактовать такую ситуацию так же, как и передачу пустого массива/коллекции.
Здравствуйте, MozgC, Вы писали:
MC>Например, насколько я помню, Рихтер писал что это сделано для большей эффективности — мол не надо создавать массив и потом его garbage-collect'ить.
В CLR via C#? Я именно после той главы и написал этот пример. Слишком уж очевидный косяк.
Эффективность тут ни при чем, это чисто проблема парсера. foo(params null) не помешало бы этому, зато позволило бы избежать конфузов.
Здравствуйте, _FRED_, Вы писали:
_FR>>>Конечно. Потому что далеко не каждый Кё>>>>foo(x) -> попугай _FR>>>а лишь при стечении некоторых обстоятельств.
Кё>>Ну будет твоя микроволновка включать гриль вместо 20 сек не всегда, а только когда в комнате темно. Суть не меняется. _FR>Ну почему сразу гриль-то? Вот в режиме настройки времени кнопка таймера устанавливает время. Мне это не мешает готовить пищу.
Внимание:
— один и тот же метод
— один и тот же параметр одного и того же типа (даже физически тот же самый объект)
— один и тот же синтаксис вызова
и при этом — разная семантика
Банальный копи-паст из обычного метода в дженерик присылает граблями по лбу.
Здравствуйте, Кодёнок, Вы писали:
Кё> foo(null, null); Кё> foo(null); // HUH WHAT THE HELL
Мне кажется, претензии вполне обоснованные. Если я написал params, меня не колышет, кто и что там передал — ps должен быть не null и содержать пусть даже пустой список — Я ЭТО ЗАПРОСИЛ ключевым словом.
А эта индусская оптимизация только вводит в диссонанс, коверкая интуитивную семантику языка.
Здравствуйте, matumba, Вы писали:
M>Мне кажется, претензии вполне обоснованные. Если я написал params, меня не колышет, кто и что там передал — ps должен быть не null и содержать пусть даже пустой список — Я ЭТО ЗАПРОСИЛ ключевым словом. M>А эта индусская оптимизация только вводит в диссонанс, коверкая интуитивную семантику языка.
int[] arr = new int[0, 1, 2];
foo(arr);//Что ожидаете в этом случае?int[] arr = null;
foo(arr);//А в этом случае?
Здравствуйте, matumba, Вы писали:
Кё>> foo(null, null); Кё>> foo(null); // HUH WHAT THE HELL
M>Мне кажется, претензии вполне обоснованные. Если я написал params, меня не колышет, кто и что там передал — ps должен быть не null и содержать пусть даже пустой список — Я ЭТО ЗАПРОСИЛ ключевым словом. M>А эта индусская оптимизация только вводит в диссонанс, коверкая интуитивную семантику языка.
Open you mind — вспомните, что для платформы .NET существует множество языков, ни один из которых не обязан поддерживать params. Как такие языки должны вызывать ваши методы? Кто и как обеспечит то, что вместо параметра-массива params не сможет придти null?
Help will always be given at Hogwarts to those who ask for it.
Здравствуйте, Кодёнок, Вы писали:
Кё>Здравствуйте, Воронков Василий, Вы писали:
ВВ>>int[] arr = new int[0, 1, 2]; ВВ>>foo(arr);//Что ожидаете в этом случае?
Кё>ожидаю ps : new object[] { new int[] {0,1,2} }
ВВ>>int[] arr = null; ВВ>>foo(arr);//А в этом случае?
Кё>ожидаю ps : new object[] { null }
Кё>Это довольно просто: params + N параметров при вызове = массив из N элементов на входе, нет?
Как уже писали, этот метод будет мертв для языков без поддержки params.
Здравствуйте, Кодёнок, Вы писали:
ВВ>>int[] arr = new int[0, 1, 2]; ВВ>>foo(arr);//Что ожидаете в этом случае? Кё>ожидаю ps : new object[] { new int[] {0,1,2} } ВВ>>int[] arr = null; ВВ>>foo(arr);//А в этом случае? Кё>ожидаю ps : new object[] { null } Кё>Это довольно просто: params + N параметров при вызове = массив из N элементов на входе, нет?
Мне вот было бы непросто. Поведение в первом случае мне не нравится совсем. Я если я пишу метод-враппер, который принимает params и передает их в другой метод с params? Что делать? Переливать из пустого в порожнее? Сейчас первый вариант работает так, как мне нужно, а второй проблемы не составляет.
Здравствуйте, samius, Вы писали:
S>Как уже писали, этот метод будет мертв для языков без поддержки params.
Еще раз пишу, что речь исключительно о синтаксисе вызова в языке c# и в самом методе и его декларации НИЧЕГО (т.е. ничего, это значит — ничего) не изменится. Языки без поддержки params это не затронет никоим образом.
Здравствуйте, Воронков Василий, Вы писали:
ВВ>Я если я пишу метод-враппер, который принимает params и передает их в другой метод с params? Что делать?
Тогда опля — пишем во враппере foo(params arr) вместо foo(arr) и имеем гарантию, что передали массив params, а не 1 параметр, независимо от контекста и типов.
Здравствуйте, Кодёнок, Вы писали:
ВВ>>Я если я пишу метод-враппер, который принимает params и передает их в другой метод с params? Что делать? Кё>Тогда опля — пишем во враппере foo(params arr) вместо foo(arr) и имеем гарантию, что передали массив params, а не 1 параметр, независимо от контекста и типов.
Здравствуйте, Кодёнок, Вы писали:
Кё>Здравствуйте, samius, Вы писали:
S>>Как уже писали, этот метод будет мертв для языков без поддержки params.
Кё>Еще раз пишу, что речь исключительно о синтаксисе вызова в языке c# и в самом методе и его декларации НИЧЕГО (т.е. ничего, это значит — ничего) не изменится. Языки без поддержки params это не затронет никоим образом.
А кто будет переписывать уже существующий код на C#?
По-моему проблема вообще не в params, а в том что null нетипизирован.
foo((object)null);
работает как надо.
Здравствуйте, samius, Вы писали:
S>А кто будет переписывать уже существующий код на C#?
Введение breaking changes не есть нечто невероятное. Тем более рефлексия и верифицируемость кода позволяют автоматическими тулсами выдать на блюдечке все потенциально проблемные места, возможно даже исправить автоматом.
S>По-моему проблема вообще не в params, а в том что null нетипизирован.
Проблема вообще не в null, см. пример с делегатами, где его нет, а проблема есть. Я поспешил с названием топика, теперь часть ответов вообще не в тему.
Здравствуйте, Кодёнок, Вы писали:
Кё>Здравствуйте, samius, Вы писали:
S>>А кто будет переписывать уже существующий код на C#?
Кё>Введение breaking changes не есть нечто невероятное. Тем более рефлексия и верифицируемость кода позволяют автоматическими тулсами выдать на блюдечке все потенциально проблемные места, возможно даже исправить автоматом.
А ради чего?
S>>По-моему проблема вообще не в params, а в том что null нетипизирован.
Кё>Проблема вообще не в null, см. пример с делегатами, где его нет, а проблема есть. Я поспешил с названием топика, теперь часть ответов вообще не в тему.
В примере с дженериком несколько неожиданно, но вполне логично. Было бы странно, если бы он работал как-то по-другому.
Здравствуйте, Кодёнок, Вы писали:
ВВ>>В твоем варианте я так не смогу. Т.е. хуже уже стало, а вот бенефиты сомнительны. Кё>Сможешь, ты видимо не понял идею. В моем варианте Bar(params args) отфорвардит готовый массив, Bar(args) создаст новый из 1 элемента.
Не понял. Давай с примерами кода. Мне в метод Foo(params) передали несколько параметров вида Foo(x, y, z). Я хочу эти параметры передать в метод Bar(params). Что я буду делать? Сейчас я могу просто передать массив args, ибо params есть тонкий сахар над массивом.