Re: C# - добавили бардака - одобряете?
От: rudzuk  
Дата: 08.09.22 08:48
Оценка: +5 :))) :))) :))) :))) :)
Здравствуйте, 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'ом добавять, заживете, наконец-то, по-людски.
avalon/3.0.1
Re: C# - добавили бардака - одобряете?
От: Aquilaware  
Дата: 08.09.22 20:35
Оценка: 154 (5) -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
    // ... красота на любом уровне "вложенности"! ...


Теперь вы видите?

"Да прозреет ослепший, да избавится от химер и иллюзий ложных." — © Я
Re[2]: C# - добавили бардака - одобряете?
От: Osaka  
Дата: 08.09.22 09:09
Оценка: :))) :)))
R>Скоро вам еще begin с end'ом добавять, заживете, наконец
На КОНЕЦЕСЛИ
Re: C# - добавили бардака - одобряете?
От: karbofos42 Россия  
Дата: 08.09.22 07:18
Оценка: 1 (1) +3 -1
Здравствуйте, Shmj, Вы писали:

S>Не кажется ли это внедрением бардака? В одном месте будут писать так в другом эдак.


Мне вообще все эти and, or, not и т.п. не нравятся.
В существующий синтаксис привычные &&, ||, ! вписать не смогли, засунули какой-то паскале-образный костыль и довольны.
Re[5]: C# - добавили бардака - одобряете?
От: karbofos42 Россия  
Дата: 08.09.22 12:29
Оценка: :))) :))
Здравствуйте, Serginio1, Вы писали:

S> Ну а мне нравится. Наконец то паттерн матчинг стал применяться. Заодно мозги немного потренировать от автоматизма


Мне ни разу в жизни еще Паттерн матчинг не понадобился. Где возникала проблема — решалось нормальной архитектурой. Как-то скептически я к таким штукам отношусь и из-за использования. Люди охотнее забивают на архитектуру, т.к. любые ошибки потом можно легко обойти сахаром языка.
Re[11]: C# - добавили бардака - одобряете?
От: karbofos42 Россия  
Дата: 09.09.22 17:26
Оценка: 127 (3) :)
Здравствуйте, Sinclair, Вы писали:

S>Если вас действительно интересует такой вопрос — не поленитесь и посмотрите дизассемблером.

S>Микроскопические методы типа First прекрасно инлайнятся, а проверки типа в случаях, когда тип известен (то есть как раз там, где можно безопасно написать items[0]), устраняются JIT-ом.

Посмотрел через ILSpy, посмотрел на sharplab, вызов метода First никуда не делся.
Я не силён в устройстве компилятора и т.п. Метод First точно может инлайниться? Он вроде в другой сборке лежит, а не в моём проекте, такое инлайнится?

S>А если этот вопрос вас не беспокоит, то старайтесь писать понятный код, дружественный к модификациям. items.First() точнее выражает намерение разработчика и дружелюбнее к будущей смене типа коллекции.


Ну, да. Мне тут намедни таск под ускорение метода прилетел. Изменил 1 строчку и получил ускорение в десяток раз.
Кто-то взял List и для него активно вызывал методы Remove и Contains. Простая замена на HashSet дала достаточный прирост скорости.
Только пришлось всё равно пробежать по коду и убедиться, что там не важен порядок элементов и я сменой коллекции ничего не нарушу.
Если бы мне пришлось попутно поменять [0] на .First(), то вот вообще не переживал бы.
А я мог и не посмотреть и не думать об особенностях и различиях обеих коллекций.
Засунул бы HashSet бездумно туда, где важен порядок элементов, лови потом весёлый баг.

S>Пока что минусов не видно.


Давно хотел и вот решил под такое дело таки попробовать BenchmarkDotNet.
  Код теста
public class Benchmark
{
    const int retry = 10;
    List<int> _items;

    public Benchmark()
    {
        _items = new List<int>(1);
        _items.Add(1);
    }

    [Benchmark]
    public bool ByAny()
    {
        bool result = false;
        for (int i = 0; i < retry; ++i)
        {
            result = _items.Any();
        }
        return result;
    }

    [Benchmark]
    public bool ByCount()
    {
        bool result = false;
        for (int i = 0; i < retry; ++i)
        {
            result = _items.Count != 0;
        }
        return result;
    }

    [Benchmark]
    public int ByIndex()
    {
        int result = 0;
        for (int i = 0; i < retry; ++i)
        {
            result = _items[0];
        }
        return result;
    }

    [Benchmark]
    public int ByFirst()
    {
        int result = 0;
        for (int i = 0; i < retry; ++i)
        {
            result = _items.First();
        }
        return result;
    }
}


  Результат
BenchmarkDotNet=v0.13.2, OS=Windows 10 (10.0.19044.1526/21H2/November2021Update)
Intel Core i3-10100F CPU 3.60GHz, 1 CPU, 8 logical and 4 physical cores
.NET SDK=6.0.400
  [Host]     : .NET 6.0.8 (6.0.822.36306), X64 RyuJIT AVX2
  DefaultJob : .NET 6.0.8 (6.0.822.36306), X64 RyuJIT AVX2


|  Method |       Mean |     Error |    StdDev |
|-------- |-----------:|----------:|----------:|
|   ByAny |  47.657 ns | 0.3115 ns | 0.2761 ns |
| ByCount |   3.235 ns | 0.0304 ns | 0.0285 ns |
| ByIndex |   6.913 ns | 0.0838 ns | 0.0784 ns |
| ByFirst | 108.889 ns | 1.4484 ns | 1.3549 ns |


Я что-то не так сделал или всё же разница в разы есть?
Re[11]: C# - добавили бардака - одобряете?
От: Евгений Акиньшин grapholite.com
Дата: 10.09.22 04:33
Оценка: 122 (4)
Здравствуйте, Sinclair, Вы писали:

K>>Last() хоть короче и понятнее записывается, чем items[items.Count — 1], а с First вообще одни минусы, как по мне.

S>Пока что минусов не видно.

А бывает еще смешней: в .net7 linq методы кое-где используют векторизацию и могут работать в 10-ки раз быстрее, чем очевидная реализация руками:

https://youtu.be/zCKwlgtVLnQ
Не шалю, никого не трогаю, починяю примус Diagrams Designer for iPad and Windows 10
Re[8]: C# - добавили бардака - одобряете?
От: Слава  
Дата: 08.09.22 13:53
Оценка: 3 (1) +3
Здравствуйте, karbofos42, Вы писали:

K>Может мне просто не попадалось задач, куда Pattern matching хорошо ложится и прямо нужная вещь.


Представьте список транзакций, к каждой из которых нужно добавить набор разрешённых действий. У транзакции есть набор признаков, штук 15.

Сейчас это сделано в виде 400* строк вложенных if'ов, и одно и то же действие может быть добавлено в нескольких местах этой скомканной простыни. Разбираться в этом очень тяжело.

Более прямой, "табличный" вид паттерн-матчинга сделал бы этот код более понятный. А понимать его надо, туда лезут 50 разных людей и никто ничего не знает.

*это не преувеличение, я только что проверил, и это старая версия кода, сейчас там строк прибавилось
C# - добавили бардака - одобряете?
От: Shmj Ниоткуда  
Дата: 08.09.22 07:09
Оценка: +3 :)
Теперь можно писать и так и эдак:

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);



Не кажется ли это внедрением бардака? В одном месте будут писать так в другом эдак.
Re[8]: C# - добавили бардака - одобряете?
От: IT Россия linq2db.com
Дата: 08.09.22 21:44
Оценка: 18 (1) +2
Здравствуйте, karbofos42, Вы писали:

K>Люди для List вместо проверки Count вызывают метод Any(). Вместо нулевого элемента запрашивают First().


Рекомендую поизучать исходники Linq.

        public static bool Any<TSource>(this IEnumerable<TSource> source)
        {
            if (source == null)
            {
                ThrowHelper.ThrowArgumentNullException(ExceptionArgument.source);
            }

            if (source is ICollection<TSource> collectionoft)
            {
                return collectionoft.Count != 0;
            }
            else if (source is IIListProvider<TSource> listProv)
            {
                // Note that this check differs from the corresponding check in
                // Count (whereas otherwise this method parallels it).  If the count
                // can't be retrieved cheaply, that likely means we'd need to iterate
                // through the entire sequence in order to get the count, and in that
                // case, we'll generally be better off falling through to the logic
                // below that only enumerates at most a single element.
                int count = listProv.GetCount(onlyIfCheap: true);
                if (count >= 0)
                {
                    return count != 0;
                }
            }
            else if (source is ICollection collection)
            {
                return collection.Count != 0;
            }

            using (IEnumerator<TSource> e = source.GetEnumerator())
            {
                return e.MoveNext();
            }
        }


С First примерно та же ситуация.
Если нам не помогут, то мы тоже никого не пощадим.
Re[2]: C# - добавили бардака - одобряете?
От: karbofos42 Россия  
Дата: 09.09.22 06:01
Оценка: +2 :)
Здравствуйте, Aquilaware, Вы писали:

A>Можно даже захватить походящее значение в переменную для дальнейшего использования:


A>
A>if (GetIQ() is < 100 and > 50 and var iq)
A>    Console.WriteLine("Hoi polloi IQ: {0}", iq);
A>


А что будет, если написать or var iq?
Почему не запись типа:
A>
A>if (var iq = GetIQ() is < 100 and > 50)
A>    Console.WriteLine("Hoi polloi IQ: {0}", iq);
A>

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

A>Теперь вы видите?


Я лично тут вижу, что кто-то написал кривые методы, которые неудобно использовать и в результате вокруг них идут какие-то костыли.
Что мешало написать так:
if (TryGetBicycle(out var bicycle))
...
else if (TryGetMotorcycle(out var motorcycle))
...
else
...

и запись короче и язык коверкать не нужно
Re[5]: C# - добавили бардака - одобряете?
От: karbofos42 Россия  
Дата: 14.09.22 12:23
Оценка: +3
Здравствуйте, Max Mustermann, Вы писали:

MM>За пределами демонстраций/обучающих сессий эта конструкция мне понадобилась примерно никогда, конечно. :D


Ну, с ?? удобно исключения бросать и дефолтные значения задавать:
_value1 = value1 ?? throw new ArgumentNullException(nameof(value1));
_value2 = value2 ?? defaultValue2;


с ?. удобно, если нужно пробраться в какую-то иерархию, где на любом уровне может быть null:
var value = root?.child1?.child2;

if (value != null)
{
...
}

без этого пришлось бы много if городить, а так это компилятор сделает и код чище выглядит.
Удобно при разборе всяких xml, json и т.п. где нельзя повлиять на наличие какого-либо объекта и не стоит падать, если в файле какой-то элемент потеряли.
Эти операторы, на мой взгляд, вполне неплохая вещь и годный сахар.
Re[2]: C# - добавили бардака - одобряете?
От: Aquilaware  
Дата: 09.09.22 11:08
Оценка: 56 (2)
Здравствуйте, vaa, Вы писали:

vaa>есть же жемчужина программирования:

vaa>https://lisp-lang.org/
vaa>https://common-lisp.net/

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

Поэтому задание для топик стартера — это написать своими руками интерпретатор Scheme (нормализованного диалекта Lisp) и в процессе прочувствовать это всё. После такого опыта дороги назад уже не будет, настолько сильным будет его влияение на сознание и на понимание происходящих процессов.

Рекомендуется всем, кто не ещё пробовал. Но конечно же, большая часть людей проигнорирует эту возможность по разным причинам. Кто-то закатит глаза со словами "опять эта функциональщина, а мне тут формы шлёпать надо", у кого-то не будет времени из-за занятости, а кто-то вообще не поймет, что тут такого особенного происходит.
Re[2]: C# - добавили бардака - одобряете?
От: _NN_ www.nemerleweb.com
Дата: 11.09.22 22:14
Оценка: 12 (1) +1
Здравствуйте, Aquilaware, Вы писали:

A>это теперь можно делать в одну строку:


A>
A>if (TryGetBicycle() is not null and var bicycle)
A>    Console.WriteLine("Bicycle owner is {0}.", bicycle.Owner);
A>


Не обязательно так многословно:

if (TryGetBicycle() is {} bicycle) ...
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[13]: C# - добавили бардака - одобряете?
От: Sinclair Россия https://github.com/evilguest/
Дата: 10.09.22 04:59
Оценка: 8 (2)
Здравствуйте, Sinclair, Вы писали:

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

K>>Посмотрел через ILSpy, посмотрел на sharplab, вызов метода First никуда не делся.
S>Это очень интересно. Действительно, почему-то вызов остаётся.
З.Ы. Посмотрел врукопашную, взяв исходник из Core https://github.com/dotnet/runtime/blob/80b7a657ee1471f20fd23f228b2576c0dbe14789/src/libraries/System.Linq/src/System/Linq/First.cs
Применение AggessiveInlining на First и TryGetFirst помогает встроить код, но в итоге почему-то всё равно остаются вызовы.
Похоже, основные оптимизации JIT попали на value-типы, а для референс-типов вроде List<T> устраняется не вся возможная косвенность.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[2]: C# - добавили бардака - одобряете?
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 08.09.22 07:29
Оценка: +2
Здравствуйте, karbofos42, Вы писали:

K>В существующий синтаксис привычные &&, ||, ! вписать не смогли, засунули какой-то паскале-образный костыль и довольны.

Основное слово привычнее!
Мне нравится, так как я бывший паскалист и новому поколению тоже понравится!
и солнце б утром не вставало, когда бы не было меня
Re: C# - добавили бардака - одобряете?
От: alexzzzz  
Дата: 08.09.22 13:26
Оценка: +2
Здравствуйте, 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# написал, это ты написал. Написать непонятно можно на любом языке с любым набором фич, даже самым примитивным. Просто пиши так, чтобы было понятно и тебе, и окружающим. Разделяй сложное на простое, создавай промежуточные переменные с говорящими названиями, расставляй скобочки... Когда понятнее значками |&!^, используй значки, когда понятнее словами, пиши слова.
Отредактировано 08.09.2022 13:28 alexzzzz . Предыдущая версия .
Re: C# - добавили бардака - одобряете?
От: _FRED_ Черногория
Дата: 08.09.22 15:45
Оценка: +2
Здравствуйте, 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.
Re[10]: C# - добавили бардака - одобряете?
От: Евгений Акиньшин grapholite.com
Дата: 09.09.22 05:58
Оценка: +2
Здравствуйте, karbofos42, Вы писали:


K>Last() хоть короче и понятнее записывается, чем items[items.Count — 1], а с First вообще одни минусы, как по мне.


В современном си шарпе пишут:

items[^1]
Не шалю, никого не трогаю, починяю примус Diagrams Designer for iPad and Windows 10
Re[4]: C# - добавили бардака - одобряете?
От: Max Mustermann  
Дата: 14.09.22 10:58
Оценка: -1 :)
Здравствуйте, Aquilaware, Вы писали:


A>
A>var vehicle = TryGetBicycle() ?? TryGetMotorcycke() ?? TryGetCar();
A>


Вот кстати да, всё не мог вспомнить, прямо дежа-вю. Точно, вот оно: полезность этого нововведения мне сильно напоминает позезность оператора "??", тоже были рассказы как теперь заживём по-новому и вах как все смогут писать код типа:
Console.WriteLine("The owner is {0}.", TryGetBicycle()?.Owner ?? TryGetMotorcycle()?.Owner ?? GetDefaultValue().Owner);


И прямо сердце замирало от открывшихся перспектив и причастности к великому...
За пределами демонстраций/обучающих сессий эта конструкция мне понадобилась примерно никогда, конечно. :D
Re[3]: C# - добавили бардака - одобряете?
От: karbofos42 Россия  
Дата: 08.09.22 07:41
Оценка: +1
Здравствуйте, Serginio1, Вы писали:

S> Мне нравится, так как я бывший паскалист и новому поколению тоже понравится!


Да я сам с паскаля начинал, потом много на Delphi 7 писал.
Мне не нравится не сами операторы, а что одно и то же в разных местах нужно по-разному писать.
Везде в программе &&, а захотел паттерн-матчинг (или как там это называется) — тут уже какой-то свой подъязык с and.
Мне такой кривой синтаксический сахар не нравится.
Re[9]: C# - добавили бардака - одобряете?
От: karbofos42 Россия  
Дата: 08.09.22 14:26
Оценка: :)
Здравствуйте, Serginio1, Вы писали:

S>Ну в лист как раз необязательно. Ибо ленивые вычисления и может запрос еще где понадобится для формирования нового запроса.

S>В запросах как раз нет вычислений пока не позовешь MoveNext
S>ToList обычно при передаче в методы, а лучше как раз передавать IEnumerable<T>. А так foreach сам раскроет IEnumerable. Но это так лирика.

Тут важно понимать внутреннее устройство. С IEnumerable в лучшем случае люди одни и те же расчёты проводили по несколько раз, т.к. коллекция попадала в несколько foreach.
В худшем — бывали трудновыявляемые баги, когда повторный прогон LINQ давал другой набор данных.
Смотришь в коде, стоит проверка на то, что 2 элемента в коллекции, а через 3 строки падает, т.к. в коллекции уже оказывается 1 элемент, хотя никто ничего не удалял.

S> В любом случае чем больше конструкций тем лучше. Пусть и не часто применяемых


В итоге часто в командах вводятся запреты на различные конструкции языка, т.к. тим лиды считают, что что-то мешает читабельности, что-то приводит к потенциальным ошибкам и т.д.
В итоге пропадает единообразие и при переходе в другую команду придётся ещё и переучиваться немного под хотелки руководства.
Re[10]: C# - добавили бардака - одобряете?
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 08.09.22 17:02
Оценка: +1
Здравствуйте, karbofos42, Вы писали:

K>Тут важно понимать внутреннее устройство. С IEnumerable в лучшем случае люди одни и те же расчёты проводили по несколько раз, т.к. коллекция попадала в несколько foreach.

K>В худшем — бывали трудновыявляемые баги, когда повторный прогон LINQ давал другой набор данных.
K>Смотришь в коде, стоит проверка на то, что 2 элемента в коллекции, а через 3 строки падает, т.к. в коллекции уже оказывается 1 элемент, хотя никто ничего не удалял.

Угу если источник будет меняться, то получишь, что угодно. Суть понимать с чем имеешь дело.
Проблемы использования IEnumerable
и солнце б утром не вставало, когда бы не было меня
Re: C# - добавили бардака - одобряете?
От: vaa  
Дата: 09.09.22 01:29
Оценка: :)
Здравствуйте, Shmj, Вы писали:

S>Теперь можно писать и так и эдак:


S>Не кажется ли это внедрением бардака? В одном месте будут писать так в другом эдак.


Так не юзай ЯП с синтаксисами!
есть же жемчужина программирования:
https://lisp-lang.org/
https://common-lisp.net/
☭ ✊ В мире нет ничего, кроме движущейся материи.
Re[9]: C# - добавили бардака - одобряете?
От: karbofos42 Россия  
Дата: 09.09.22 04:32
Оценка: :)
Здравствуйте, IT, Вы писали:

IT>Рекомендую поизучать исходники Linq.


Так я видел и в курсе.
Разве нет разницы между items[0] и items.First() в плане, что во втором случае добавляется проверка типа коллекции?
Вроде мелочь, а вроде лишняя работа и лишнее ветвление непонятно зачем.
Last() хоть короче и понятнее записывается, чем items[items.Count — 1], а с First вообще одни минусы, как по мне.
Re[2]: C# - добавили бардака - одобряете?
От: Shtole  
Дата: 09.09.22 08:17
Оценка: +1
Здравствуйте, Aquilaware, Вы писали:

A>Вместо такого ужаса теперь посмотрим на произведение исскуства, на картину Художника:


A>
A>if (TryGetBicycle() is not null and var bicycle)
A>    Console.WriteLine("Bicycle owner is {0}.", bicycle.Owner);
A>else if (TryGetMotorcycle() is not null and var motorcycle)
A>    Console.WriteLine("Motorcycle owner is {0}.", motorcycle.Owner);
A>else if (TryGetCar() is not null and var car)
A>    Console.WriteLine("Car owner is {0}.", car.Owner);
A>else
A>    // ... красота на любом уровне "вложенности"! ...
A>


Для произведения искусства тут слишком много копипасты. Как по мне, я бы сделал список типов (Bicycle, Motorcycle, Car) и проверял соответствие каждому, а при выводе в консоль использовал бы метаданные (имя типа или назначенная ему человекочитаемая строка). А если бы набор TryGetX() был внешним и не поддавался переписыванию, сделал бы список хотя бы методов (TryGetBicycle, TryGetMotorcycle, TryGetCar).
Do you want to develop an app?
Отредактировано 14.09.2022 14:14 Shtole . Предыдущая версия .
Re[11]: C# - добавили бардака - одобряете?
От: karbofos42 Россия  
Дата: 09.09.22 09:04
Оценка: :)
Здравствуйте, Serginio1, Вы писали:

S>Угу если источник будет меняться, то получишь, что угодно. Суть понимать с чем имеешь дело.


Ну, вот и у linq я вижу варианты использования и это нужная вещи, а у этого кривого синтаксического сахара — нет.
Возможно где-то его использование и оправдано и у меня просто таких задач не было.
Предвижу, что раньше люди боялись объёмных ветвлений и начинали задумываться над архитектурой, переписывая нормально, что такие проверки становились в принципе не нужны.
Теперь объёмные проверки можно легко и коротко записывать, поэтому чего бы дублирующих условий везде не напихать и плевать как это скажется на производительности и сколько лишнего будет код делать.
Re[4]: C# - добавили бардака - одобряете?
От: karbofos42 Россия  
Дата: 09.09.22 12:21
Оценка: :)
Здравствуйте, Aquilaware, Вы писали:

A>То, что предлагаете вы — это никак не ровные методы, это исторический костыль. Проблема с этим костылем в том, что нельзя сделать вот так:


не костыль, а try-parse паттерн же

A>А нужно как всегда извращаться в упражнении рука-писать.


ну, для предыдущего варианта подвезли pattern-matching, могли и для этого что-то в язык тогда добавить, чтобы удобнее было использовать
Re[12]: C# - добавили бардака - одобряете?
От: Sinclair Россия https://github.com/evilguest/
Дата: 10.09.22 03:20
Оценка: +1
Здравствуйте, karbofos42, Вы писали:
K>Посмотрел через ILSpy, посмотрел на sharplab, вызов метода First никуда не делся.
Это очень интересно. Действительно, почему-то вызов остаётся.
K>Я не силён в устройстве компилятора и т.п. Метод First точно может инлайниться? Он вроде в другой сборке лежит, а не в моём проекте, такое инлайнится?
Да, такое должно инлайниться. Почему этого не происходит — отдельный вопрос.
Будет время — я посмотрю логи джита.
K>Ну, да. Мне тут намедни таск под ускорение метода прилетел. Изменил 1 строчку и получил ускорение в десяток раз.
K>Кто-то взял List и для него активно вызывал методы Remove и Contains. Простая замена на HashSet дала достаточный прирост скорости.
И это — очень типичная ситуация. Примерно так и выглядит оптимизация шарпа в 99% случаев.
K>Только пришлось всё равно пробежать по коду и убедиться, что там не важен порядок элементов и я сменой коллекции ничего не нарушу.
В идеальном случае пробежка выполняется при помощи перепрогона тестов. Если тестов мало — то да, надо смотреть глазами.
Хотя это менее надёжно — мало ли, что где можно посмотреть.
K>Если бы мне пришлось попутно поменять [0] на .First(), то вот вообще не переживал бы.
K>А я мог и не посмотреть и не думать об особенностях и различиях обеих коллекций.
K>Засунул бы HashSet бездумно туда, где важен порядок элементов, лови потом весёлый баг.

K>| Method | Mean | Error | StdDev |

K>|-------- |-----------:|----------:|----------:|
K>| ByAny | 47.657 ns | 0.3115 ns | 0.2761 ns |
K>| ByCount | 3.235 ns | 0.0304 ns | 0.0285 ns |
K>| ByIndex | 6.913 ns | 0.0838 ns | 0.0784 ns |
K>| ByFirst | 108.889 ns | 1.4484 ns | 1.3549 ns |
K>[/code]
K>[/cut]

K>Я что-то не так сделал или всё же разница в разы есть?

Вы всё сделали верно. Снимаю шляпу. На досуге поразбираюсь, откуда такой провал в производительности.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[2]: C# - добавили бардака - одобряете?
От: Caracrist https://1pwd.org/
Дата: 11.09.22 11:58
Оценка: +1
Здравствуйте, Aquilaware, Вы писали:

A>var bicycle = TryGetBicycle();
A>if (bicycle != null)
A>    Console.WriteLine("Bicycle owner is {0}.", bicycle.Owner);
A>


A>это теперь можно делать в одну строку:


A>if (TryGetBicycle() is not null and var bicycle)
A>    Console.WriteLine("Bicycle owner is {0}.", bicycle.Owner);
A>


A>Почему такая возможность важна? Потому что иногда это безумно удобно во вложенных if'ах, так как позволяет обойтись одним уровнем вложенности вместо плохо читаемой "ёлочки" c углублениями.


Могли бы взять синтаксис C++17

Получилось бы тоже в одну строчку:
if (var bicycle = TryGetBicycle(); bicycle != null)
    Console.WriteLine("Bicycle owner is {0}.", bicycle.Owner);

~~~~~
~lol~~
~~~ Single Password Solution
Re[3]: C# - добавили бардака - одобряете?
От: Shtole  
Дата: 11.09.22 12:47
Оценка: +1
Здравствуйте, Caracrist, Вы писали:

C>Могли бы взять синтаксис C++17


C>Получилось бы тоже в одну строчку:

C>
C>if (var bicycle = TryGetBicycle(); bicycle != null)
C>    Console.WriteLine("Bicycle owner is {0}.", bicycle.Owner);
C>

C>

Сишарповский вариант лично мне нравится горазо больше.

А почему объявление переменной с инициализацией было не сделать выражением?

if ((var bicycle = TryGetBicycle()) != null)
    Console.WriteLine("Bicycle owner is {0}.", bicycle.Owner);
Do you want to develop an app?
Re[4]: C# - добавили бардака - одобряете?
От: _NN_ www.nemerleweb.com
Дата: 11.09.22 22:32
Оценка: +1
Здравствуйте, Aquilaware, Вы писали:

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


_NN>>
_NN>>if (TryGetBicycle() is {} bicycle) ...
_NN>>


A>Короче на пару слов, но вот вообше не понятно что это такое без подьема доки.


А я как раз не додумался, что можно писать «is not null and var».
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[4]: C# - добавили бардака - одобряете?
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 08.09.22 08:58
Оценка:
Здравствуйте, karbofos42, Вы писали:

S>> Мне нравится, так как я бывший паскалист и новому поколению тоже понравится!


K>Да я сам с паскаля начинал, потом много на Delphi 7 писал.

K>Мне не нравится не сами операторы, а что одно и то же в разных местах нужно по-разному писать.
K>Везде в программе &&, а захотел паттерн-матчинг (или как там это называется) — тут уже какой-то свой подъязык с and.
K>Мне такой кривой синтаксический сахар не нравится.

Ну а мне нравится. Наконец то паттерн матчинг стал применяться. Заодно мозги немного потренировать от автоматизма
и солнце б утром не вставало, когда бы не было меня
Re[6]: C# - добавили бардака - одобряете?
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 08.09.22 12:49
Оценка:
Здравствуйте, karbofos42, Вы писали:

K>Мне ни разу в жизни еще Паттерн матчинг не понадобился. Где возникала проблема — решалось нормальной архитектурой. Как-то скептически я к таким штукам отношусь и из-за использования. Люди охотнее забивают на архитектуру, т.к. любые ошибки потом можно легко обойти сахаром языка.

Ну это старое мышление. Аналогично тому как появился Linq. Многие так говорили. Однако со временем Linq набрал популярность.
и солнце б утром не вставало, когда бы не было меня
Re: C# - добавили бардака - одобряете?
От: xma  
Дата: 08.09.22 12:53
Оценка:
Здравствуйте, Shmj, Вы писали:

S>if (i is 1 or 3 and not (5 and not 5))

S>Не кажется ли это внедрением бардака?

наглядность уменьшается, да — на автопилоте уже не понятно чё как и к чему ..
Re[7]: C# - добавили бардака - одобряете?
От: karbofos42 Россия  
Дата: 08.09.22 13:10
Оценка:
Здравствуйте, Serginio1, Вы писали:

S> Ну это старое мышление. Аналогично тому как появился Linq. Многие так говорили. Однако со временем Linq набрал популярность.


LINQ мне нравится, но при этом уже устал от бессмысленных записей.
Люди для List вместо проверки Count вызывают метод Any(). Вместо нулевого элемента запрашивают First().
Недавно вообще блестящее место исправлял:
List<Item> values ...;
List<Item> otherValues ...;
if (values.Any(item => длинное_условие_ && !otherValues.Contains(item)))
{
  Item item = values.First(то_же_самое_выражение_что_в_Any);
  ...
}

Благо хоть приучились ToList() вызывать, а то бы повторных расчётов было в разы больше.
Но Linq всё же уместен в нормальном коде и вещь полезная.
Может мне просто не попадалось задач, куда Pattern matching хорошо ложится и прямо нужная вещь.
Что попадалось и в голову приходило — это было быстрыми костылями к кривой реализации основного кода.
Ну, и Linq нормально в язык вписался, естественно и непринуждённо.
Отредактировано 08.09.2022 13:11 karbofos42 . Предыдущая версия .
Re: C# - добавили бардака - одобряете?
От: vsb Казахстан  
Дата: 08.09.22 13:28
Оценка:
Здравствуйте, 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 — найти статический анализатор, который сам будет следить за соблюдением.
Re[8]: C# - добавили бардака - одобряете?
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 08.09.22 13:45
Оценка:
Здравствуйте, karbofos42, Вы писали:

K>Благо хоть приучились ToList() вызывать, а то бы повторных расчётов было в разы больше.

Ну в лист как раз необязательно. Ибо ленивые вычисления и может запрос еще где понадобится для формирования нового запроса.
В запросах как раз нет вычислений пока не позовешь MoveNext
ToList обычно при передаче в методы, а лучше как раз передавать IEnumerable<T>. А так foreach сам раскроет IEnumerable. Но это так лирика.

K>Может мне просто не попадалось задач, куда Pattern matching хорошо ложится и прямо нужная вещь.

K>Что попадалось и в голову приходило — это было быстрыми костылями к кривой реализации основного кода.

Ну ПМ просто хорошь для всяких рекурсивных деревьев и прочее. Он пришел из функциональщины, но полезен там где много ветвлений с кучей вариантов условий.
Да часть можно архитектурно решить, но много и нельзя.

В любом случае чем больше конструкций тем лучше. Пусть и не часто применяемых
и солнце б утром не вставало, когда бы не было меня
Re: C# - добавили бардака - одобряете?
От: white_znake  
Дата: 08.09.22 15:22
Оценка:
Здравствуйте, Shmj, Вы писали:



S>Не кажется ли это внедрением бардака? В одном месте будут писать так в другом эдак.


Не одобряю.
Язык вообще должен быть лакончиным. C# уже перегружен ключевыми словами и языковыми конструкциями.
Re[2]: C# - добавили бардака - одобряете?
От: vaa  
Дата: 09.09.22 01:27
Оценка:
Здравствуйте, Aquilaware, Вы писали:



A>Например, классика:


A>
A>var bicycle = TryGetBicycle();
A>if (bicycle != null)

или просто 
[cs]
dynamic boo = getboo();
foo(boo);

void foo(A b);
void foo(B b);
void foo(C b);
void foo(object b);
☭ ✊ В мире нет ничего, кроме движущейся материи.
Отредактировано 09.09.2022 1:32 Разраб . Предыдущая версия .
Re[9]: C# - добавили бардака - одобряете?
От: Shtole  
Дата: 09.09.22 07:53
Оценка:
Здравствуйте, Слава, Вы писали:

С>Представьте список транзакций, к каждой из которых нужно добавить набор разрешённых действий. У транзакции есть набор признаков, штук 15.

С>Сейчас это сделано в виде 400* строк вложенных if'ов, и одно и то же действие может быть добавлено в нескольких местах этой скомканной простыни. Разбираться в этом очень тяжело.

PM уважаю, как и функциональный подход в принципе, но в данном случае вопрос: а нельзя ли как-то это всё «раскодировать» (перевести из кода во что-то другое)? Или в DSL, или в data-файл. Я бы в эту сторону подумал.
Do you want to develop an app?
Отредактировано 09.09.2022 10:22 Shtole . Предыдущая версия .
Re[3]: C# - добавили бардака - одобряете?
От: Aquilaware  
Дата: 09.09.22 10:55
Оценка:
Здравствуйте, karbofos42, Вы писали:

K>
K>if (TryGetBicycle(out var bicycle))
K>

K>и запись короче и язык коверкать не нужно

То, что предлагаете вы — это никак не ровные методы, это исторический костыль. Проблема с этим костылем в том, что нельзя сделать вот так:

var vehicle = TryGetBicycle() ?? TryGetMotorcycke() ?? TryGetCar();


А нужно как всегда извращаться в упражнении рука-писать. Это прям как в Java, где нет out и ref параметров функций, и поэтому люди вынуждены придумывать свои исторические костыли.

Зачем, если всё это можно сделать средствами языка? Например, был бы полноценный Optional<T> или уже сам тип данных подразумевает null значение.
Re[10]: C# - добавили бардака - одобряете?
От: Sinclair Россия https://github.com/evilguest/
Дата: 09.09.22 13:53
Оценка:
Здравствуйте, karbofos42, Вы писали:
K>Так я видел и в курсе.
K>Разве нет разницы между items[0] и items.First() в плане, что во втором случае добавляется проверка типа коллекции?
Если вас действительно интересует такой вопрос — не поленитесь и посмотрите дизассемблером.
Микроскопические методы типа First прекрасно инлайнятся, а проверки типа в случаях, когда тип известен (то есть как раз там, где можно безопасно написать items[0]), устраняются JIT-ом.
А если этот вопрос вас не беспокоит, то старайтесь писать понятный код, дружественный к модификациям. items.First() точнее выражает намерение разработчика и дружелюбнее к будущей смене типа коллекции.
K>Вроде мелочь, а вроде лишняя работа и лишнее ветвление непонятно зачем.
K>Last() хоть короче и понятнее записывается, чем items[items.Count — 1], а с First вообще одни минусы, как по мне.
Пока что минусов не видно.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[10]: C# - добавили бардака - одобряете?
От: Слава  
Дата: 09.09.22 17:02
Оценка:
Здравствуйте, Shtole, Вы писали:

S>PM уважаю, как и функциональный подход в принципе, но в данном случае вопрос: а нельзя ли как-то это всё «раскодировать» (перевести из кода во что-то другое)? Или в DSL, или в data-файл. Я бы в эту сторону подумал.


Для этого нужен отбеливатель и шуруповёрт с набором саморезов. В отбеливатель засунуть исполнительных копчёных сотрудников, а шуруповёртом закрутить саморезы в головы белым энергичным сотрудникам. А без этого они так и будут тикеты создавать и закрывать.
Re[3]: C# - добавили бардака - одобряете?
От: vsb Казахстан  
Дата: 10.09.22 03:36
Оценка:
Здравствуйте, Aquilaware, Вы писали:

A>Поэтому задание для топик стартера — это написать своими руками интерпретатор Scheme (нормализованного диалекта Lisp) и в процессе прочувствовать это всё. После такого опыта дороги назад уже не будет, настолько сильным будет его влияение на сознание и на понимание происходящих процессов.


A>Рекомендуется всем, кто не ещё пробовал. Но конечно же, большая часть людей проигнорирует эту возможность по разным причинам. Кто-то закатит глаза со словами "опять эта функциональщина, а мне тут формы шлёпать надо", у кого-то не будет времени из-за занятости, а кто-то вообще не поймет, что тут такого особенного происходит.


Я писал. Компилятор даже. Нет, не понял, что там особого. Ничего особого в схеме нет. Убогий игрушечный недоязычок, даже до джаваскрипта не дотягивает. А уж интерпретатор — там и вовсе ничего интересного. С компилятором там хоть какие-то вопросы возникают в голове.

Вот хаскель — да. Там ничего писать не надо. Просто сидеть и учить, фича за фичей. Подбирая выпадающий мозг.
Отредактировано 10.09.2022 3:39 vsb . Предыдущая версия . Еще …
Отредактировано 10.09.2022 3:37 vsb . Предыдущая версия .
Отредактировано 10.09.2022 3:36 vsb . Предыдущая версия .
Re[3]: C# - добавили бардака - одобряете?
От: _NN_ www.nemerleweb.com
Дата: 11.09.22 22:23
Оценка:
Здравствуйте, Caracrist, Вы писали:

C>Получилось бы тоже в одну строчку:

C>
C>if (var bicycle = TryGetBicycle(); bicycle != null)
C>    Console.WriteLine("Bicycle owner is {0}.", bicycle.Owner);
C>

C>

Тут идея в использовании сопоставление с образцом в условиях.
Правда вышла небольшая накладочка и не всегда можно просто заменить if на switch:

      string? F() { return ""; }


      public int M2()
      {
        if (F() is object o && o.GetHashCode() == 1)
        {
          return 1;
        }
        else if (F() is {} s)
        {
          return s.Length;
        }
        else
        {
          return 2;
        }
    }

    public int M2() 
    {
        return F() switch
        {
          object o when o.GetHashCode() == 1 => 1, // && или and не подходят
          {} s => 1,
          _ => 2         
        };
    }
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[3]: C# - добавили бардака - одобряете?
От: Aquilaware  
Дата: 11.09.22 22:27
Оценка:
Здравствуйте, _NN_, Вы писали:

_NN>
_NN>if (TryGetBicycle() is {} bicycle) ...
_NN>


Короче на пару слов, но вот вообше не понятно что это такое без подьема доки.
Re[5]: C# - добавили бардака - одобряете?
От: Aquilaware  
Дата: 19.09.22 17:58
Оценка:
Здравствуйте, Max Mustermann, Вы писали:

MM>За пределами демонстраций/обучающих сессий эта конструкция мне понадобилась примерно никогда, конечно.


Всё приходит с опытом. ?? — на самом деле один из самых частоисподьзуемых операторов. Но не для всех, например, при императивном подходе это как козе баян. А вот при функциональном это как диаманд.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.