int i = int.Parse(Console.ReadLine());
if (i == 1 || i == 3 && !(i == 5 && i != 5))
Console.WriteLine(1);
if (i is 1 or 3 and not (5 and not 5))
Console.WriteLine(2);
Не кажется ли это внедрением бардака? В одном месте будут писать так в другом эдак.
Здравствуйте, Shmj, Вы писали:
S>Не кажется ли это внедрением бардака? В одном месте будут писать так в другом эдак.
Мне вообще все эти and, or, not и т.п. не нравятся.
В существующий синтаксис привычные &&, ||, ! вписать не смогли, засунули какой-то паскале-образный костыль и довольны.
Здравствуйте, karbofos42, Вы писали:
K>В существующий синтаксис привычные &&, ||, ! вписать не смогли, засунули какой-то паскале-образный костыль и довольны.
Основное слово привычнее!
Мне нравится, так как я бывший паскалист и новому поколению тоже понравится!
и солнце б утром не вставало, когда бы не было меня
Здравствуйте, Serginio1, Вы писали:
S> Мне нравится, так как я бывший паскалист и новому поколению тоже понравится!
Да я сам с паскаля начинал, потом много на Delphi 7 писал.
Мне не нравится не сами операторы, а что одно и то же в разных местах нужно по-разному писать.
Везде в программе &&, а захотел паттерн-матчинг (или как там это называется) — тут уже какой-то свой подъязык с and.
Мне такой кривой синтаксический сахар не нравится.
Здравствуйте, Shmj, Вы писали:
S> Теперь можно писать и так и эдак:
S>
S> int i = int.Parse(Console.ReadLine());
S> if (i == 1 || i == 3 && !(i == 5 && i != 5))
S> Console.WriteLine(1);
S> if (i is 1 or 3 and not (5 and not 5))
S> Console.WriteLine(2);
S>
S> Не кажется ли это внедрением бардака? В одном месте будут писать так в другом эдак.
Скоро вам еще begin с end'ом добавять, заживете, наконец-то, по-людски.
Здравствуйте, karbofos42, Вы писали:
S>> Мне нравится, так как я бывший паскалист и новому поколению тоже понравится!
K>Да я сам с паскаля начинал, потом много на Delphi 7 писал. K>Мне не нравится не сами операторы, а что одно и то же в разных местах нужно по-разному писать. K>Везде в программе &&, а захотел паттерн-матчинг (или как там это называется) — тут уже какой-то свой подъязык с and. K>Мне такой кривой синтаксический сахар не нравится.
Ну а мне нравится. Наконец то паттерн матчинг стал применяться. Заодно мозги немного потренировать от автоматизма
и солнце б утром не вставало, когда бы не было меня
Здравствуйте, Serginio1, Вы писали:
S> Ну а мне нравится. Наконец то паттерн матчинг стал применяться. Заодно мозги немного потренировать от автоматизма
Мне ни разу в жизни еще Паттерн матчинг не понадобился. Где возникала проблема — решалось нормальной архитектурой. Как-то скептически я к таким штукам отношусь и из-за использования. Люди охотнее забивают на архитектуру, т.к. любые ошибки потом можно легко обойти сахаром языка.
Здравствуйте, karbofos42, Вы писали:
K>Мне ни разу в жизни еще Паттерн матчинг не понадобился. Где возникала проблема — решалось нормальной архитектурой. Как-то скептически я к таким штукам отношусь и из-за использования. Люди охотнее забивают на архитектуру, т.к. любые ошибки потом можно легко обойти сахаром языка.
Ну это старое мышление. Аналогично тому как появился Linq. Многие так говорили. Однако со временем Linq набрал популярность.
и солнце б утром не вставало, когда бы не было меня
Здравствуйте, Serginio1, Вы писали:
S> Ну это старое мышление. Аналогично тому как появился Linq. Многие так говорили. Однако со временем Linq набрал популярность.
LINQ мне нравится, но при этом уже устал от бессмысленных записей.
Люди для List вместо проверки Count вызывают метод Any(). Вместо нулевого элемента запрашивают First().
Недавно вообще блестящее место исправлял:
Благо хоть приучились ToList() вызывать, а то бы повторных расчётов было в разы больше.
Но Linq всё же уместен в нормальном коде и вещь полезная.
Может мне просто не попадалось задач, куда Pattern matching хорошо ложится и прямо нужная вещь.
Что попадалось и в голову приходило — это было быстрыми костылями к кривой реализации основного кода.
Ну, и Linq нормально в язык вписался, естественно и непринуждённо.
Здравствуйте, Shmj, Вы писали:
S>Теперь можно писать и так и эдак:
S>
S>int i = int.Parse(Console.ReadLine());
S>if (i == 1 || i == 3 && !(i == 5 && i != 5))
S> Console.WriteLine(1);
S>if (i is 1 or 3 and not (5 and not 5))
S> Console.WriteLine(2);
S>
S>Не кажется ли это внедрением бардака? В одном месте будут писать так в другом эдак.
Это же не C# написал, это ты написал. Написать непонятно можно на любом языке с любым набором фич, даже самым примитивным. Просто пиши так, чтобы было понятно и тебе, и окружающим. Разделяй сложное на простое, создавай промежуточные переменные с говорящими названиями, расставляй скобочки... Когда понятнее значками |&!^, используй значки, когда понятнее словами, пиши слова.
Здравствуйте, Shmj, Вы писали:
S>Теперь можно писать и так и эдак:
S>
S>int i = int.Parse(Console.ReadLine());
S>if (i == 1 || i == 3 && !(i == 5 && i != 5))
S> Console.WriteLine(1);
S>if (i is 1 or 3 and not (5 and not 5))
S> Console.WriteLine(2);
S>
Прикольно. Некрасиво, но пользу несёт однозначно.
S>Не кажется ли это внедрением бардака? В одном месте будут писать так в другом эдак.
Вариант 1 — смириться. Пишут и ладно.
Вариант 2 — поставить правило в команде и следить за соблюдением.
Вариант 3 — найти статический анализатор, который сам будет следить за соблюдением.
Здравствуйте, karbofos42, Вы писали:
K>Благо хоть приучились ToList() вызывать, а то бы повторных расчётов было в разы больше.
Ну в лист как раз необязательно. Ибо ленивые вычисления и может запрос еще где понадобится для формирования нового запроса.
В запросах как раз нет вычислений пока не позовешь MoveNext
ToList обычно при передаче в методы, а лучше как раз передавать IEnumerable<T>. А так foreach сам раскроет IEnumerable. Но это так лирика.
K>Может мне просто не попадалось задач, куда Pattern matching хорошо ложится и прямо нужная вещь. K>Что попадалось и в голову приходило — это было быстрыми костылями к кривой реализации основного кода.
Ну ПМ просто хорошь для всяких рекурсивных деревьев и прочее. Он пришел из функциональщины, но полезен там где много ветвлений с кучей вариантов условий.
Да часть можно архитектурно решить, но много и нельзя.
В любом случае чем больше конструкций тем лучше. Пусть и не часто применяемых
и солнце б утром не вставало, когда бы не было меня
Здравствуйте, karbofos42, Вы писали:
K>Может мне просто не попадалось задач, куда Pattern matching хорошо ложится и прямо нужная вещь.
Представьте список транзакций, к каждой из которых нужно добавить набор разрешённых действий. У транзакции есть набор признаков, штук 15.
Сейчас это сделано в виде 400* строк вложенных if'ов, и одно и то же действие может быть добавлено в нескольких местах этой скомканной простыни. Разбираться в этом очень тяжело.
Более прямой, "табличный" вид паттерн-матчинга сделал бы этот код более понятный. А понимать его надо, туда лезут 50 разных людей и никто ничего не знает.
*это не преувеличение, я только что проверил, и это старая версия кода, сейчас там строк прибавилось
Здравствуйте, Serginio1, Вы писали:
S>Ну в лист как раз необязательно. Ибо ленивые вычисления и может запрос еще где понадобится для формирования нового запроса. S>В запросах как раз нет вычислений пока не позовешь MoveNext S>ToList обычно при передаче в методы, а лучше как раз передавать IEnumerable<T>. А так foreach сам раскроет IEnumerable. Но это так лирика.
Тут важно понимать внутреннее устройство. С IEnumerable в лучшем случае люди одни и те же расчёты проводили по несколько раз, т.к. коллекция попадала в несколько foreach.
В худшем — бывали трудновыявляемые баги, когда повторный прогон LINQ давал другой набор данных.
Смотришь в коде, стоит проверка на то, что 2 элемента в коллекции, а через 3 строки падает, т.к. в коллекции уже оказывается 1 элемент, хотя никто ничего не удалял.
S> В любом случае чем больше конструкций тем лучше. Пусть и не часто применяемых
В итоге часто в командах вводятся запреты на различные конструкции языка, т.к. тим лиды считают, что что-то мешает читабельности, что-то приводит к потенциальным ошибкам и т.д.
В итоге пропадает единообразие и при переходе в другую команду придётся ещё и переучиваться немного под хотелки руководства.
Здравствуйте, Shmj, Вы писали:
S>Теперь можно писать и так и эдак:
S>int i = int.Parse(Console.ReadLine());
S>if (i == 1 || i == 3 && !(i == 5 && i != 5))
S> Console.WriteLine(1);
S>if (i is 1 or 3 and not (5 and not 5))
S> Console.WriteLine(2);
S>Не кажется ли это внедрением бардака? В одном месте будут писать так в другом эдак.
Полностью согласен, помню, на C# версии 1.0 можно было то же самое написать вот так вот:
S>int i = int.Parse(Console.ReadLine());
if (i == 1 || i == 3)
Console.WriteLine(1);
но дублировать "i" не очень-то здорово, поэтому-то
if (i is 1 or 3)
Console.WriteLine(2);
рулит.
Help will always be given at Hogwarts to those who ask for it.
Здравствуйте, karbofos42, Вы писали:
K>Тут важно понимать внутреннее устройство. С IEnumerable в лучшем случае люди одни и те же расчёты проводили по несколько раз, т.к. коллекция попадала в несколько foreach. K>В худшем — бывали трудновыявляемые баги, когда повторный прогон LINQ давал другой набор данных. K>Смотришь в коде, стоит проверка на то, что 2 элемента в коллекции, а через 3 строки падает, т.к. в коллекции уже оказывается 1 элемент, хотя никто ничего не удалял.
Здравствуйте, Shmj, Вы писали:
S>Не кажется ли это внедрением бардака? В одном месте будут писать так в другом эдак.
Совсем нет, потому что теперь можно сделать вот так в одну строку:
if (GetIQ() is < 100 and > 50)
Console.WriteLine("Hoi polloi");
Можно даже захватить походящее значение в переменную для дальнейшего использования:
if (GetIQ() is < 100 and > 50 and var iq)
Console.WriteLine("Hoi polloi IQ: {0}", iq);
Очень удобно. Или например вместо часто используемой проверки на null:
var bicycle = TryGetBicycle();
if (bicycle != null)
Console.WriteLine("Bicycle owner is {0}.", bicycle.Owner);
это теперь можно делать в одну строку:
if (TryGetBicycle() is not null and var bicycle)
Console.WriteLine("Bicycle owner is {0}.", bicycle.Owner);
Почему такая возможность важна? Потому что иногда это безумно удобно во вложенных if'ах, так как позволяет обойтись одним уровнем вложенности вместо плохо читаемой "ёлочки" c углублениями.
Например, классика:
var bicycle = TryGetBicycle();
if (bicycle != null)
{
Console.WriteLine("Bicycle owner is {0}.", bicycle.Owner);
}
else
{
var motorcycle = TryGetMotorcycle();
if (motorcycle != null)
{
Console.WriteLine("Motorcycle owner is {0}.", motorcycle.Owner);
}
else
{
var car = TryGetCar();
if (car != null)
{
Console.WriteLine("Car owner is {0}.", car.Owner);
}
else
{
// ... намученный баян который идет глубоко вниз и конкретно долбит мозг на 5-7-м уровнях вложенности ...
}
}
}
Вместо такого ужаса теперь посмотрим на произведение исскуства, на картину Художника:
if (TryGetBicycle() is not null and var bicycle)
Console.WriteLine("Bicycle owner is {0}.", bicycle.Owner);
else if (TryGetMotorcycle() is not null and var motorcycle)
Console.WriteLine("Motorcycle owner is {0}.", motorcycle.Owner);
else if (TryGetCar() is not null and var car)
Console.WriteLine("Car owner is {0}.", car.Owner);
else// ... красота на любом уровне "вложенности"! ...