Клиенту кода поиска должно быть все равно, откуда тянутся данные. Если он будет знать, что данные тянутся из базы и нужно это оптимизировать, то это - нарушение инкапсуляции.
Именно поэтому у кверей отложенное выполнение. Это позволяет передать клиенту "коллекцию", которая не будет создавать никакой нагрузки, пока клиент не начнет ее перечислять. И если он возьмет оттуда только одну запись и на этом остановится, то остальные данные подтянуты из базы не будут.
Для задачи поиска получать 1 запись - нетипично. Если вам нужно получать ровно одну запись, то если результата поиска оказалось больше одного, то это ошибка и исключительная ситуация, которую тоже надо обрабатывать, а вы просто ее отбрасываете ("l.First()").
"Последнее действие и т.д." - тут вы нарушаете принцип Single responsibility (единственной обязанности), т.к. "последнее действие" - это бизнес-логика и она должна быть отделена от инфраструктуры (вытаскивание записей из базы). Т.е. ваш "поисковик" должен вернуть все записи, которые он нашел, а клиент (например, UI) уже решает, как ему поступать если результатов нет, результат один или результатов много.
Тем не менее - "1 абзац: Требуется получить один результат" означает, что скорее всего у вас есть более серьезная проблема с архитектурой вашего приложения.
Я в таких ситуациях предпочитаю делать свой тип исключения и бросать его, т.к. оставлять оригинальное исключение - нарушение инкапсуляции, т.к. клиенту этого метода должно быть совершенно все равно, каким именно образом осуществляется поиск.
Да, клиент этого кода должен оборачивать этот вызов в try/catch, если у он знает, как обрабатывать эту исключительную ситуацию - "результат должен быть, а его нет".
Без повторений символов это выглядело бы как-то так: "^(?=.*а)(?=.*л)(?=.*к)(?=.*с)". С повторениями нужно еще посмотреть. Вам обязательно нужно решение этой задачи через регулярные выражения или вам просто нужно решить эту задачу?
Форма сама может реализовывать INotifyProgress, чтобы не усложнять.
Так этот интерфейс вам и нужен, чтобы обновлять состояние прогресс-бара (в общем случае - произвольного клиента, которому интересно состояние вашего LongRunningTaskPerformer). Соответственно, в конеце DoStep1 вызываете Notify(33), в конце DoStep2 - Notify(66) и дальше в том же духе. Соответственно, форма, реагируя на эти вызовы, обновляет состояние прогресс-бара.
dordzhiev: действительно, хабр не понимает span, но понимает font. Вот такой заменой регэкспом все получается: 'span style="color:([.*]);"' -> 'font color="\1"', 'span' -> 'font'.
@UbuRus: Как раз ООП и ФП прекрасно живут вместе. Я, например, люблю функциональный стиль и активно его использую, хоть и пишу на C#. Вот, есть хорошая статья - blog.ploeh.dk/2014/03/10/solid-the-next-step-is-fu... там C# и F#, но, думаю, идею уловить это вам не помешает, почитайте, может вам будет интересно.
@UbuRus: Сколько лет JS, сколько TS - конечно, у них там еще не все идеально. Почему вы называете классы TS иллюзией? Если они выглядят как классы и ведут себя как классы, то, на мой, взгляд, они является классами. Ваш код на JS - это тоже иллюзия, в конечном счете все оказывается 1 и 0 и никакой красоты там не остается. На JS пишется красивый и быстрый код, т.к. в поисках решения проблемы того, что естественным образом на JS код получается уродливым и медленным, уже сломано миллион копий, придумана куча паттернов и заоптимизированны JS-движки. Я не говорю, что JS - плох, я говорю о том, что TS - это инструмент, который позволяет решить некоторые задачи эффективнее, чем JS. И, судя по вопросу ОПа, вполне возможно, что он как раз в той ситуации, в которой TS может ему помочь.
@UbuRus: в этой же строчке автор пишет: "If you love JavaScript, warts and all, but wish it had classes, modules, interfaces and static typing then TypeScript is the answer.". Это как раз то, что надо автору вопроса. Я полностью согласен с вашим ответом выше "В JavaScript ООП не нужно", т.е. с тем, что не нужно писать на JavaScript к ОО парадигме. Нет смысла писать в оо-стиле на асме или, вообще, в байт-коде, но можно писать в оо-стиле на шарпе или джаве, которые, в конечном счете, окажутся байт-кодом. Тут та же самая история. Нужно уже просто начать воспринимать JavaScript как байт-код для браузера и создавать новые абстракции, как это сделали в MS с тайп-скриптом.
Я вам показал пример со строкой только чтобы вы увидели, что в сериализованном файле в явном виде лежат имена полей и их значения, типы со сложными полями ничем не отличаются. Откройте файл и посмотрите сами - вы легко можете восстановить структуру любого объекта.