Как стать автором
Обновить

Комментарии 167

Классическая статья с "актуальным" материалом (на самом деле ради рекламы).

«With-выражения» — теперь всякие клонаторы не нужны? Хотя надо еще посмотреть как оно с deep clone работает.

Никак оно с deep clone не работает. Или вы хотите работать с record-ами, в которые некоторые поля указывают на изменяемые объекты?

Глубокого клонирования не будет в любом случае. Поверхностное — да.
НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь

Ну вот кто-то счёл, что ваш комент образец трэша и неадеквата и намекнул вам об этом минусом.

НЛО прилетело и опубликовало эту надпись здесь

Ну так дайте развёртный анализ, я ему даже плюс поставлю, и даже если не буду полностью с ним согласен. Сейчас же ваша позиция выглядит безосновательной в стиле "мне не нравится XXX". Вы не предоставили аргументы в защиту своей позиции — получили закономерные минусы, тоже без аргументов.

НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь
И если создатели плывут в сторону от строгой объектно-ориентированности

… которой там никогда не было.


Ну ладно, ок, первые версии еще ничего. Но как только у вас появились inline delegates, точно стало понятно, что это язык со смешанной парадигмой. А LINQ — следующий шаг в этом направлении. И дальше, дальше, дальше.


Ну не нравится вам, ок, не нравится. Вы пишете, что вам не нравится. Кому-то не нравится ваш комментарий, и они выражают свое отношение к вашему комментарию тем способом, который на этом ресурсе принят.

Минусы без аргументации почему — это ничто.

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

Ну, вы не перегибайте так.
НЛО прилетело и опубликовало эту надпись здесь
Например, в описанной Вами ситуации многие не считают разумным тратить время и усилия почитать

Те, кто не читает, вообще никакого мнения про ваш текст не имеют, поэтому вполне логично, что ни минусов, ни плюсов они не ставят :) Я имею в виду тех, кто читает. Мне, например, тема С# 9 интересна, поэтому я прочитал и статью, и комментарии под ней. Ваш комментарий мне тоже абсолютно честно показался каким-то нелепым. Минусы я ставить не могу, да и не стал бы даже если бы мог, т.к. мне это просто не важно, но прекрасно понимаю тех, кто ставит.
НЛО прилетело и опубликовало эту надпись здесь
Минус без аргументации обычно означает «я искренне считаю, что вы написали хрень, но диалог с вами мне не настолько интересен, чтобы раскрывать подробно свою мысль»


критика должна быть конструктивной, иначе какой в ней смысл

Вообще-то, у критики бывают разные задачи, и не все из них требуют конструктива.

тогда это не критика, а личное суждение

А почему вы противопоставляете критику личному суждению? Это не обязательно взаимоисключающие вещи.


А главное, сверху даже критики-то не обещал никто.

Ну потому что личое суждение, например — «ты дурак»
Конструктивная критика — «я не согласен с вашим мнением, т.к. вы не учли такие-то и такие-то моменты»
Первое никому ничего не даст, со второго можно чему-то научиться

Конструктивная критика — «я не согласен с вашим мнением, т.к. вы не учли такие-то и такие-то моменты»

Вот только она при этом все еще может остаться личным суждением. Например, потому что эти моменты важны только по личному суждению критикующего.


Первое никому ничего не даст, со второго можно чему-то научиться

А почему вы решили, что стоит задача кого-то чему-то научить?

Вот только она при этом все еще может остаться личным суждением


я не очень понимаю, как
если мы спорим про программирование, и я, например, говорю что у линковского .find сложность О(log(n)) и поэтому на небольших коллекциях им искать — самое оно, как это может быть личным суждением? Оно ошибочное, и доказать это — минута гугления. Мой оппонент будет прав, даже если лично мне он неприятен

А почему вы решили, что стоит задача кого-то чему-то научить?


или научиться
А иначе зачем ввязываться в дискуссии в интернете? Я могу понять в личном общении, там и поорать можно, и в рыло оппоненту просунуть (или получить), жизнь как есть
А в интернете-то…
если мы спорим про программирование, и я, например, говорю что у линковского .find сложность О(log(n)) и поэтому на небольших коллекциях им искать — самое оно, как это может быть личным суждением?

"Самое оно" — это и есть личное суждение.


Оно ошибочное, и доказать это — минута гугления.

Неа, нельзя доказать, что метод x на небольших коллекциях не самое оно. Можно доказать, что у него другая сложность.


А иначе зачем ввязываться в дискуссии в интернете?

Напомню, что началось все с того, что человек поставил минус именно потому, что он не хотел ввязываться в дискуссию.

если мы спорим про программирование, и я, например, говорю что у линковского .find сложность О(log(n)) и поэтому на небольших коллекциях им искать — самое оно, как это может быть личным суждением?

«Самое оно» — это и есть личное суждение.


Его элементарно можно опровергнуть; а чье-то личное мнение попробуйте опровергнуть, ха

Напомню, что началось все с того, что человек поставил минус именно потому, что он не хотел ввязываться в дискуссию.


ну так оно и выглядит как «сам дурак»
Его элементарно можно опровергнуть

Попробуйте.


ну так оно и выглядит как «сам дурак»

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

Попробуйте.

docs.microsoft.com/en-us/dotnet/api/system.collections.generic.list-1.find?view=net-5.0
Исходное предположение неверно, эрго, последующий вывод — тоже
Но свою задачу прекрасно выполняет


Какую?
Исходное предположение неверно, эрго, последующий вывод — тоже

Nope. "Я считаю", что на небольших коллекциях сложность не имеет значения, поэтому этот метод — самое оно.


Какую?

Продемонстрировать отношение к высказанному в комментарии тезису.

Nope. «Я считаю», что на небольших коллекциях сложность не имеет значения, поэтому этот метод — самое оно.


ну так это совсем другое исходное предположение, никакого отношения к моему не имеет; соответственно, весь наш спор бессмысленнен

Продемонстрировать отношение к высказанному в комментарии тезису.


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

Так и ваш исходный пример не имеет никакого отношения к критике, выраженной в виде личного мнения, так что все логично.


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

Обратная связь как раз есть: рейтинг комментария. И он интересен не только написавшим, но и остальным. Я вот смотрю на рейтинги.

Так и ваш исходный пример не имеет никакого отношения к критике, выраженной в виде личного мнения, так что все логично.


не, критика в виде личного мнения была бы КГ/АМ, а не ссылки на страницы документации

Обратная связь как раз есть: рейтинг комментария.


Он ничего не выражает и не обьясняет
Может, человек просто не с той ноги встал. Может, он просто не в теме (см. эффект Даннинга-Крюгера). Может, он и имел что-то конкретное в виду, но мы этого не узнаем
А мне бы хотелось не полагаться просто на чье-то мнение, а видеть аргументы сторон, чтоб я сам мог принять решение
не, критика в виде личного мнения была бы КГ/АМ, а не ссылки на страницы документации

Вооот. Это типичный пример личного суждения. Вы считаете, что критика в виде личного суждения была бы [...]. Это, заметим, ваша критика чужого поведения. Иными словами, критика, которую вы даете, не соответствует вашим же требованиям к критике, и при этом подтверждает мой тезис.


Повторюсь еще раз: возможна критика, являющаяся личным суждением, но при этом не сводящаяся к КГ/АМ.


Он ничего не выражает и не обьясняет

Отнюдь. Он выражает некую совокупную реакцию читателей на комментарий. А объяснять он ничего и не должен.


А мне бы хотелось не полагаться просто на чье-то мнение, а видеть аргументы сторон, чтоб я сам мог принять решение

Вам бы хотелось — это ваши личные пожелания, не правда ли?

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


Кри́тика (от фр. critique из др.-греч. κριτική τέχνη «искусство разбирать, суждение») — анализ, оценка о явлениях какой-либо области человеческой деятельности[1]. Задачами критики являются:

  • выявление противоречий;
  • выявление ошибок и их разбор;
  • разбор (анализ), обсуждение чего-либо с целью дать оценку (например, литературная критика);
  • исследование, научная проверка достоверности, подлинности чего-либо (например, критика текста, критика исторических источников);
  • оценка;


Так вот, личное суждение "это плохо" вполне является оценкой. Все прекрасно совпало.

такую оценку может дать даже тетя Циля с Привоза
ценность ее будет невелика

Для вас — возможно. Для кого-то другого — возможно, нет.


А главное, от того, что для вас эта оценка не ценна, она не перестает быть критикой (если, конечно, это замышлялось как критика).

И мне удивительно, что меня минусуют прям все, кому не лень.

Неуместная метафора — вы преувеличиваете.


Минусы без аргументации почему — это ничто.

А плюсы?

НЛО прилетело и опубликовало эту надпись здесь
Может быть, я и не прав, но, когда плюсуют — это согласие и поддержка твоего поста.
Но вот если минусуют…

А если минусуют — несогласие. Очень логично.

НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь

Проектный или командный code style convention, желательно с проверкой лиентервми.

НЛО прилетело и опубликовало эту надпись здесь

… а когда чего-то из этого нет, вам язык не поможет все равно. Так что не в языке проблема, нет.

НЛО прилетело и опубликовало эту надпись здесь

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

НЛО прилетело и опубликовало эту надпись здесь
И каждое сомнительное нововведение будет уводить от строгой дисциплины, как снежный ком.

Не было там никогда "строгой дисциплины", поэтому и уводить неоткуда.


Красота любой игры в строгих правилах: шахматы, футбол.

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


Но код — он и не игра, и не искусство, он просто средство достижения цели. Слишком строгие правила усложняют достижение цели, а не способствуют ему.

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

Мне они как раз (почти) всем нравятся. Я просто продолжаю логику исходного комментария о "новомодных чудовищах".

Понял. Мне тоже нравятся, вот я и подумал, что ж с ними не так-то… Спасибо за уточнение!

НЛО прилетело и опубликовало эту надпись здесь
И у меня есть предчувствие, что эффективность кода при этом снижается, тяжеловесность растёт.

Не знаю как в мире C#, но в мире PHP, например, принято при выходе новых синтаксических и подобных фич сравнивать не только код "было"-"стало", но бенчмарки прогонять.


А в наличии только одного оптимального варианта я очень сомневаюсь. Хотя бы потому что метрики оптимальности/эффективности могут быть разными: тут нам важны циклы процессора, тут потребляемая память, тут отсутствие блокировок, а тут гарантии времени выполнения.


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

НЛО прилетело и опубликовало эту надпись здесь
Поэтому, вне зависимости от ОС и процессора можно ±спрогнозировать эффективность кода.

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

НЛО прилетело и опубликовало эту надпись здесь
Другое дело, если Вы пишете конкретный проект под конкретного заказчика.

Ну вот я не пишу конкретный проект под конкретного заказчика. Я даже версию Windows, на которой будет код выполняться, не всегда точно знаю.


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

Оценить его и сейчас можно, в этом отношении ничего не изменилось.

НЛО прилетело и опубликовало эту надпись здесь

Как это связано с тем, что я сказал?

НЛО прилетело и опубликовало эту надпись здесь
Из двух заданных Вами вопросов, я отвечал именно на этот.

Я вроде бы не задавал никакого вопроса.


Если Вы пишете ± универсал-проект -рекомендовал бы протестить на узкие места, которые видны на любом компе.

… и почему вы думаете, что это не сделали?

НЛО прилетело и опубликовало эту надпись здесь
облегчают читаемость и уменьшают многословность

Программисты 90% времени читают код, лишь 10% пишут, поэтому мне кажется, что зря настолько легко отмахиваетесь от аргумента "основная работа становится проще".

НЛО прилетело и опубликовало эту надпись здесь
А если ещё дедлайн. Безусловно, в этом случае новые фичи — ценная вещь.

Ровно наоборот. Если у вас дедлайн, хвататься за новый фичи можно только в том случае, если без них никак, во всех остальных случаях надо сидеть на том, что уже известно.


а это именно надстройки над языком

Да нет, это сам язык и есть. Как вы отличаете "язык" от "надстроек"?

НЛО прилетело и опубликовало эту надпись здесь
Конечно, сорри, но мы как собаки Павлова…

Нет, мы не как собаки Павлова.


Есть классика, базовые конструкции языка.

Что такое "базовые конструкции языка"?


У меня нет подтверждающей информации, но есть предчувствие, что транслятор переводит их в те же самые коллекции и итераторы, а уже после этого транслирует их.

После фразы "у меня нет информации, но есть предчувствие", становится понятно, почему вы не можете с этим разобраться. Если что, информация о том, как работает LINQ, открыта.


транслятор переводит их в те же самые коллекции и итераторы, а уже после этого транслирует их.

Нет. LINQ в query-синтаксисе просто переводится в method-синтаксис, а дальше происходит обычный вызов. О каких "коллекциях и итераторах" можно говорить в случае IQueryable?


А, главное, чем это отличается от foreach, using или lock? Или они теперь тоже не базовые конструкции языка?

НЛО прилетело и опубликовало эту надпись здесь
К сожалению, здесь Вас огорчу… [...] Конечно же, это не прямой рефлекс собачки Павлова,

Ну вот видите. Собирались огорчить, а на самом деле со мной согласились.


Этим вопросом отдельно не занимался… есть первичные конструкции IList, IQueryable, например.

Ни то, ни другое не является конструкцией языка.


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

Когда я хочу быстрый JOIN, я делаю его в БД, и IEnumerable мне здесь поможет очень слабо.


Но, в любом случае, LINQ по функциональности на голову выше IList, IQueryable.

Это бессмысленное утверждение. LINQ — это набор инструментов, использующих, в том числе, IQueryable. Не будет IQueryable — не будет LINQ.


Поэтому это не базовая конструкция языка, а надстройка.

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


Но, в любом случае, LINQ — не существовало в момент рождения C#.

В момент рождения C# не существовало даже дженериков. И… что?

НЛО прилетело и опубликовало эту надпись здесь
в каждом конкретном случае есть только один оптимальный вариант.

Оптимальный по какому набору критериев?


примерно представляю для себя, каким образом это превращается в код.

Именно что "примерно". А потом там проходит JIT, и начинается веселье.


Новые фичи, на мой взгляд, не добавляют функциональности, а лишь в некоторых случаях облегчают читаемость и уменьшают многословность [...] И всё это положено в угоду мелких удобствам

Ну так облегчение читаемости — это не "мелкое удобство".

НЛО прилетело и опубликовало эту надпись здесь
Представьте мультивложеный LINQ, украшенный многоэтажными лямбдами [...] потом понять [...] слабореально.

Так это не улучшение читаемости, если вы не можете это понять.


К сожалению, когда предлагают нечто удобное, этим сразу же начинают злоупотреблять

… давайте поэтому не предлагать ничего удобного?

Представьте мультивложеный LINQ, украшенный многоэтажными лямбдами…

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

НЛО прилетело и опубликовало эту надпись здесь

Можете привести пример такой "жести", когда запрос в linq хуже читается чем в процедурном стиле? Мне вот что-то не приходит в голову.


Зато вот какой пример не придумаешь — лучше выглядит именно в Linq, например:


return Layers.Last().Neurons.OrderByDescending(n => n.Output).First();

(отсюда, возможно этот вопрос ещё не удалён)

НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь

… если вы часто делаете join/union, повод задуматься, не взять ли вам другую коллекцию для "быстродействия". Вместо "итераторов".

НЛО прилетело и опубликовало эту надпись здесь

Хэш-таблицы во всех их вариантах.

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

… а что это меняет с точки зрения оптимизации производительности?


Речь идет о том, где его нельзя прописать, там нужно оптимизировать скорость.

Гм. Что значит "нельзя прописать хэш"? Я вас не понимаю. Использование хэш-таблицы вместо другой коллекции — это и есть один из способов "оптимизации скорости".


Надеюсь, мы не трогаем БД?

Нет, не трогаем, потому что тут разговор немедленно сместится в плоскость "LINQ против самописных запросов", а я это терпеть не могу.

НЛО прилетело и опубликовало эту надпись здесь
Это означает, что я сам решаю, где хэш/C/ASM, а где оставить linq

Я в процессе написания софта, как вы выражаетесь, "на продажу", тоже сам решаю, где какую оптимизацию использовать. Так в чем отличие?


Хэш- далеко не оптимальная оптимизация

А я и не говорил, что она оптимальная. Я сказал, есть повод задуматься, не взять ли ее.


Вы можете вычислять таблицу умножения напрямую, а можете поместить её в хэш.

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


Напомните мне — побеседуем отдельно. Слишком объемная тема

… я так понимаю, фраза "я это терпеть не могу" вам не понятна?

Мне что-то интересно стало.


Вот есть два источника данных IEnumerable<Order> orders и IEnumerable<Customer> customers. Нужно для каждого ордера вывести его кастомера. Ну то есть, грубо говоря, orders.Join(customers, order => order.CustomerId, customer => customer.Id, someSelector). Как вы предлагаете "руками прописать итератор", чтобы было заведомо быстрее, чем дефолтная реализация в LINQ?

НЛО прилетело и опубликовало эту надпись здесь

Код покажите. Ваше словесное описание мне совершенно не понятно, особенно в части "синхронизировав две коллекции в одну".

НЛО прилетело и опубликовало эту надпись здесь

Во-первых, это никак не решает задачу Join, озвученную выше. То есть вообще никак. И никак нельзя перенести принцип.


А во-вторых вы по каждой коллекции проходите дважды, а это в общем случае недопустимо (и в этот момент, извините, ни о какой производительности говорить уже нельзя), хотя для решения вашей задачи это вообще низачем не надо. Подозреваю, кстати, что с учетом этой оговорки Enumerable.Zip(a, b, (a, b) => a+b) будет быстрее, чем ваше решение.

НЛО прилетело и опубликовало эту надпись здесь
Это именно join в простейшем виде. Учебный вариант.

Нет. Опишите, пожалуйста, своими словами операцию Join.


Покажите место, где я прохожу коллекцию дважды. Его там нет

Вот оно:


_a = a.GetEnumerator();
int countA = a.Count();
//...
_a.MoveNext();

Вы в курсе, что делает Enumerable.Count()?

НЛО прилетело и опубликовало эту надпись здесь

Ну то есть сначала вы рекомендуете переписывать Join на собственный итератор, а потом не можете показать пример такого итератора, который бы корректно работал с Join (и был бы заведомо быстрее версии LINQ).


(вот за это я и не люблю микрооптимизации)


Да, кстати, а почему вы считаете, что ваша версия быстрее вот такой:


IEnumerable<int> MemberwiseSum(IEnumerable<int> a, IEnumerable<int> b)
{
  using (IEnumerator<int> ai = a.GetEnumerator())
  using (IEnumerator<int> bi = b.GetEnumerator())
  while (ai.MoveNext() && ai.MoveNext())
    yield return ai.Current+bi.Current;
}

(проверку на равенство длин добавлять лень, она тривиальная, зато в остальном этот код корректнее вашего)

НЛО прилетело и опубликовало эту надпись здесь

Да, действительно, у меня там опечатка, должно быть


while (ai.MoveNext() && bi.MoveNext())

Но это не объясняет, почему ваш код должен быть быстрее. И тем более не объясняет, как же сделать Join.

НЛО прилетело и опубликовало эту надпись здесь
Идея понравилась

… то есть вы, рекомендуя "собственные итераторы", даже не поинтересовались, как работает существующий код?


Неплохо бы поставить Reset перед началом итераций.

Зачем? Там свежий итератор. Более того, итераторы даже не обязаны его поддерживать:


The Reset method is provided for COM interoperability. It does not necessarily need to be implemented; instead, the implementer can simply throw a NotSupportedException.

(https://docs.microsoft.com/en-us/dotnet/api/system.collections.generic.ienumerator-1?view=net-5.0#remarks)


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


Использование using — под вопросом.

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


Или вы во внутренности foreach тоже не смотрели никогда?


Собственно, все вот эти нюансы с Reset, MoveNext и Dispose — это то, почему не надо писать свои итераторы, пока вы можете этого избежать.


Dispose уложит Вашу коллекцию, особенно, если она статическая.

Что значит "уложит"?


(это не говоря о том, что этот код не оперирует "коллекциями", он оперирует последовательностями)

НЛО прилетело и опубликовало эту надпись здесь

Ну то есть вы давали советы "руками прописывать итераторы, если критические узлы", не разобравшись в том, как работают итераторы в .net.


Ну ок.

НЛО прилетело и опубликовало эту надпись здесь
Впечатление, что Вы не прочли камент, на который ответили…

Там явно написано " даже не поинтересовался".

НЛО прилетело и опубликовало эту надпись здесь
Вы, кстати, тоже не поинтересовались

Нет, неверно, потому что код, который я вам привел, основан на существующем.


потому как на Вашу опечатку ai.MoveNext() && ai.MoveNext() компилятор обычно ругается

… вот только этот код никогда не видел компилятора, я его набрал прямо в окне комментария.

НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь

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

НЛО прилетело и опубликовало эту надпись здесь

… вот только в личку не надо, потому что мы говорим о пользе для всех читающих.

Наверное, у коллекций есть несколько итераторов — первой свежести и не первой.

Нет, зато бывают использованные и неиспользованные итераторы.


так понятно, что по его мнению, в предложенный им модуль коллекции поступают только уже с reset

Вам понятно неправильно. Мне передают IEnumerable (который, кстати, не коллекция). Он не может быть "с Reset" или "без Reset", он IEnumerable, у него единственная допустимая операция — GetEnumerator.


Поэтому необходимо сохранить текущий, сделать reset, а потом восстановить.

Нет, не "необходимо". Контракт IEnumerator явно говорит, что новый итератор спозиционирован перед началом коллекции, поэтому Reset бесполезен:


Initially, the enumerator is positioned before the first element in the collection. At this position, Current is undefined. Therefore, you must call MoveNext to advance the enumerator to the first element of the collection before reading the value of Current.
НЛО прилетело и опубликовало эту надпись здесь
Если Вы пишете универсальную процедуру, то должны предусмотреть, что коллекции на входе находятся не на reset

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

НЛО прилетело и опубликовало эту надпись здесь
Мы априори не знаем, какое положение итератора при передаче коллекции параметром, вернее, знаем — текущее.

При передаче нам последовательности итератора еще не существует. Он возникает в тот момент, когда мы делаем GetEnumerator. И его положение, согласно контракту — перед первым элементом последовательности на момент вызова. Это то, что нам известно из контракта IEnumerable/IEnumerator.


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

Мы не можем его ни сохранить, ни восстановить. Единственный данный нам гарантированный инструмент — это двигать итератор вперед (на то он и итератор).


Вот вам иллюстрация невозможности: стандартный сгенеренный из yield return энумератор не поддерживает Reset вообще. Если вы его вызовете, ваш код упадет.

НЛО прилетело и опубликовало эту надпись здесь
IEnumerable — интерфейс.

… вот только это не итератор. Это последовательность. А итератор — IEnumerator.


Когда Вы передаете коллекцию параметром — текущее значение итератора сохраняется.

У коллекции (скажем, у List<T>) может вообще не быть никакого "текущего значения итератора". А IEnumerable может быть не только поверх коллекции.


В Вашем фрагменте кода попробуйте передать итератор как параметр — я тоже попробую) и сделать Current

Но зачем мне передавать итератор как параметр, если все стандартные API работают с IEnumerable? Зачем мне создавать себе дополнительные сложности? Потому и в условии изначальной задачи был IEnumerable.

bobby001, извините, вы точно уверены, что понимаете как работают итераторы в C#? С каждым вашим постом у меня всё больше складывается впечатление, что вы не до конца понимаете о чём говорите...

НЛО прилетело и опубликовало эту надпись здесь

Тем временем вот вам еще один пример итератора, который не поддерживает Reset. А его вы получите, скажем, из File.ReadLines, системного вызова. И еще один, после которого становится понятно, что от Reset скорее надо ожидать эксепшн, чем что-либо еще.

НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь

Вот только для Join это принципиально невозможно. Вы точно понимаете, что делает Join?

НЛО прилетело и опубликовало эту надпись здесь

Ээээ… вообще не понимаю, что вы имеете в виду.


Вот есть коллекция заказов, в каждом заказе есть идентификатор покупателя, есть рядом коллекция покупателей (с идентификаторами). Что, по вашему, делает операция join по идентификатору покупателя?

НЛО прилетело и опубликовало эту надпись здесь
Join в данном случае выкладывает одну таблицу, состоящую из данных двух таблиц.

Каким образом сопоставляются данные двух таблиц/коллекций?


Ну банально, на примере. Вот Customers (id: name):


1: Ariane
2: John
3: Andre


Вот Orders (id: customer_id: amount):


1: 3: $50
2: 1: $15
3: 3: $50
4: 2: $25
5: 1: $12
6: 3: $40


И как же они "объединяются"?

НЛО прилетело и опубликовало эту надпись здесь

Я не знаю, что такое "одномерная табличка". Можете просто результирующие строчки написать?

НЛО прилетело и опубликовало эту надпись здесь

Но нет же. То есть вообще нет. Вы сделали группировку и сумму. А я просил join.

НЛО прилетело и опубликовало эту надпись здесь

Ровно тем, что я написал выше: вы сделали группировку и сумму, которых я не просил.

Ну и зачем вы SUM и GROUP BY сюда приплели?
Напишите просто JOIN и покажите результат его работы.

«Выражение with по-прежнему будет копировать весь объект с сохранением типа среды выполнения:»

Если свойство не простой тип, а ссылочный, ссылка с обоих объектов будет на один адрес памяти?
Разумеется.
С# — молодец, не сдается! Его теснят и теснят другие языки, а старичок уходить не хочет!
.NET Core одна из самых прогрессивных платформ текущего времени, о чём вы? Наверное думаете до сих пор, что это язык для десктопных приложений под винду? )

C# обошёл Java в удобстве, вдохновил появление Kotlin, является основным языком для самой популярной среды разработки игр Unity, поддерживается Xamarin'ом, да и WebAssymbly скорее всего массово придёт в наши браузеры через Blazor, потому что всё остальное отстаёт сильнее.
Не спорю, камрад. Просто так нечасто бывает, что язык/технология появилась в одной среде, заслужила там со временем почет и уважение, а потом по мере устаревания смогла приспособиться к совершенно другой среде, и там очень неплохо себя показывать. Поэтому C# — респект.

Про какую среду вы говорите? Web vs Desktop?
Так Asp.Net Web Forms появился с самого начала и на нем сколько всякого энтерпрайза написано. Переписывать и переписывать. Так что C# в вебе всегда был и будет))

Больше интересовали апдейты для .net 5. Делаем перформанс тесты и не верим глазам)). На ровном месте 5-10 процентов прироста. В некоторых случаях и того больше. Оч круто.

devblogs.microsoft.com/dotnet/performance-improvements-in-net-5

Вот статья, кто еще не видел.

Даже завидно как-то по белому.

Я один тут вижу влияние фанатов Typescript? (P.S я сам веб разработчик на ts и то, куда он сейчас катится, мне не очень нравится) Не так давно смотрел описание RC для Typescript 4.1, там народ тоже с ума сошел в плане добавления новых видов дженериков… Ах, да… Это же одни и те же люди…


Мне лично кажется, что подобными конструкциями для расширения типов будут созданы только проблемы… Из полезного вижу только init'ы и switch шаблоны

НЛО прилетело и опубликовало эту надпись здесь

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


А кто, собственно, сказал, что нынешняя команда C# должна мыслить в ключе ООП?

НЛО прилетело и опубликовало эту надпись здесь
C# это объектно-ориентированный язык.

Это уже очень давно не чисто объекто-ориентированный язык. Википедия, прямо скажем, честно пишет: "multi-paradigm programming language encompassing static [...] functional, [...] object-oriented (class-based), [...] programming disciplines".


И это, что характерно, к лучшему.

«Вульгарные отростки» — это всё лишь очередные и очевидные шаги в сторону удобства использования C# в рамках функциональной парадигмы (records, деконструкторы, улучшения в patterns matching и т.д.). И это хорошо, потому что C# богатый мультипарадигменный язык, где функциональная часть немного (или много?) хромает, а уж с ООП частью всё в порядке добрые десятки лет.
И опыт показывает, что понимание и умение мыслить в ключе ООП явно не достаточно, чтобы getting things done без боли и страданий. Иначе мы бы все сейчас пользовались условной Java 5 или C# 2.0.
На мой взгляд, самое жуткое, что случилось с шарпом — «программы верхнего уровня». Если такое станет тенденцией — прощай, понятность благодаря структурированности. Можно прикрутить функциональщину, можно много чего прикрутить, но откручивать нечто (чёткую структуру) от системы, делать фактически исключение, которое нужно теперь запоминать и знать, и говорить, что так понятнее — это странно. Тем более, что открываешь IDE, делаешь проект — и вот оно всё, прописано и понятно.
Ну это мелочи, право слово. Вообще не вижу ситуации, где это может как-то смутить, разве что совсем новичков. Просто убрали немного бойлерплейта в интуитивно понятном контексте.
Именно это, конечно, мелочь. Но звоночек пугающий. Выпилили пустую переменную, выпилили структуру типа для простоты, потом сделают using, как namespace в PHP, потом ещё какого сахара (или вообще — тьфу-тьфу — неявного «ясного» поведения) добавят — и аккуратный шарп превратится не то в JS, не то в Python.
Я примерно догадываюсь, от куда ноги у этого страха растут (всё завалят фичами и сахаром, настанет хаос и апокалипсис). В своё время обожглись на С++локе, но потом передули на Javоду, извините за каламбур.
Они распространяются на один единственный метод (Main) на всю программу. И добавили их фактически чтобы всякие однофайловые лямбды писать было проще без лишних отступов, ну и для обучения, по вкусу. Какие тенденции, какие потери структурированности, вообще не понятно.

Можно теперь написать
foreach (int i in 0..n);
если энумератор к range прикрутить.

так можно или нельзя
НЛО прилетело и опубликовало эту надпись здесь

Потому что будет сумасшедший breaking change. Одного этого аргумента достаточно уже.

НЛО прилетело и опубликовало эту надпись здесь
Может не быть совместимости, наверное в этом проблема

Не "может не быть", а "точно не будет". Это ровно то, что я написал выше: сумасшедший breaking change.

НЛО прилетело и опубликовало эту надпись здесь
Мож ещё придумают…

Что придумают? Как сделать это не-breaking change? Вероятность этого пренебрежимо мала, разве что это будет параллельная существующей иерархия типов (то есть, фактически, две системы типов вместо одной, а кому это надо?).


придумали же, например null-значения в ненулевых типах, например bool?

Нет, в типе bool как не было, так и нет null. null есть в Nullable<bool>, а это совсем другой тип.


Правда, в GetString одни иероглифы…

Не знаю, никогда не видел иероглифов в GetString (если, конечно, я изначально не положил эти иероглифы в данные). Может быть, дело в том, что у меня "стандартная" англоязычная локаль? Но с nullable-типами это точно никак не связано.

Nullable<bool> t = null;
Console.WriteLine("t: " + t.ToString());
t = true;
Console.WriteLine("t: " + t.ToString());
t = false;
Console.WriteLine("t: " + t.ToString());

дает


t: 
t: True
t: False

Никаких иероглифов.

НЛО прилетело и опубликовало эту надпись здесь

В Type.ToString я тоже иероглифов никогда не видел. Но, впрочем, дело даже не в этом. Дело в том, что поведение typeof(bool).ToString() не менялось когда добавили Nullable<T>. И это — обратная совместимость, так что на какие "побочные эффекты" вы жалуетесь, не очень понятно.

Зарегистрируйтесь на Хабре, чтобы оставить комментарий