Это копия, сохраненная 12 июля в 00:33.
Скачать тред: только с превью, с превью и прикрепленными файлами.
Второй вариант может долго скачиваться. Файлы будут только в живых или недавно утонувших тредах. Подробнее
Если вам полезен архив М.Двача, пожертвуйте на оплату сервера.
1. Ресурсы:
— https://dotnet.microsoft.com/learn
— https://ru.stackoverflow.com/a/416585/422180
— https://metanit.com
— https://professorweb.ru
2. С# для веб
— https://docs.microsoft.com/ru-ru/aspnet/core
3. C# для десктопа
— https://docs.microsoft.com/ru-ru/dotnet/desktop
4. С# для игр
— https://ru.stackoverflow.com/a/609901/422180
5. С# для мобильной разработки
— https://docs.microsoft.com/ru-ru/dotnet/maui
6. Годные ютуб-каналы
— https://www.youtube.com/c/CODEBLOG
— https://www.youtube.com/c/AndreyShyrokoriadov
— https://www.youtube.com/c/DevJungles
— https://www.youtube.com/user/Shmachilin
Шапка: https://pastebin.com/HT7Hi6FD
Прошлый тред: >>3002293 (OP)
Кто такой, чем известен?
Ох, ебать. Дождались таки нормального переката, слава Биллу.
![9011267.jpg](https://2ch.life/pr/thumb/3097760/17112879019240s.jpg)
На самом деле - я помню времена, когда первым постом была еще доп лит-ра. Но я не могу списочек найти. Воооот. Так что да.
Eto.Forms - годный нативный гуй-фреймворк для взрослых сеньоров.
Хороши твои ето формс но порой хочется просто поредачить ксамлы. Не надо свое фанбойство несколько перекатов продвигать
Просто я вот как не пытался. В результате - я вместо Startup - делаю класс ConfigApp.cs в котором делаю литерли то же самое, что было в Startup. Плюс, если отхожу от контроллеров - просто делаю классы, которые называю хендлерами-сервисами, и они те же контрллеры, просто без ASP'шной фигни, а в остальном - так же - в минимал апи стиле описал роутинг, а работа в этих хендлерах-сервисах.
В общем. Я не понимаю, чи я тупой и не знаю как готовить, чи годится это только для совсем узкого круга задач. Поясните, кто реально в проде использует, как вы их готовите?
Я думаю это чисто для микросервисов фича. Типо описать всю приложуху в одном Program.cs файле в меньше чем 500-600 строчек. Удобно жеж
Что хочу: сделать новый конфиг dotnet new для вскода, в котором будет лежать сопутствующий launch.json при создании.
Читал https://learn.microsoft.com/en-us/dotnet/core/tools/custom-templates
Но чёт не понял что там именно в template.json надо написать чтобы в итоге получался файл с кастомной инфой.
1. Как после dotnet build получить путь собранного бинарника? Verbosity выставить и парсить ответочку чтобы путь оттуда выковырнуть, а-ля dotnet build --verbosity n и оттуда брать CopyFilesToOutputDirectory? Есть что-то лаконичнее (кроме явного указания самому билдеру куды пихать output)?
2. Можно ли потом в вскодовской launch.json конфигурации как-то автоматически вписывать путь к бинарнику сразу в "program":?
Ну, это какие-то совсем микро-микро-сервисы.
Обычно у тебя все же там надо к БД подключаться, надо какие-то обработчики сообщений из очереди и это в рамках одного микросервиса, плюс всякие модельки и прочее. Да даже взгляни на то что майки как пример микросервисной архитектуры(eshop) показывают, если все делать это в одном файле - будет лютая каша.
>Поясните, кто реально в проде использует, как вы их готовите?
В проде нет. Только для тестовых стендах для каких-то совсем микрописечных моков или прототипов. И то, если это используется более чем одного раза, то проще свой нормальный шаблон взять и там сделать норамльно.
>Я думаю это чисто для микросервисов фича.
Суть микросервисов, совсем не в том, что они маленькие.
> порой хочется просто поредачить ксамлы
В формсах есть хамл.
> Не надо свое фанбойство несколько перекатов продвигать
Это не моё фанбойство. Это - баланс. Как только прибегает авалония-фанбой и заявляет, что авалония - единственный UI-фреймворк, мне приходится восставать из мёртвых и показывать мимокрокам, что есть альтернативы.
Не придуривайся.
Суть микросервисов, в том что они являются минимальной денницей деплоя, и в случае, если какой-то из них сломается, упадет и прочее - вся остальная система продолжает работать и большая часть пользователей даже не заметит, если какой-то сервис лег. В идеале, они еще горизонтально масштабироваться могут, но так не всегда выходит из-за бизнес-требований и требований к надежности.
А размер - у них может быть и вполне жирненький. Средний микросервис - это где-то 3-4к строк кода, если мы что-то реально полезное делаем.
>В формсах есть хамл.
ну а чем бы ему не быть. это ж просто описание кода в виде хмл
другой вопрос - а чего можно добиться этим описанием? а ровно столько же сколько и кодом.
А чего можно добиться кодом? являются ли контролы ето.формса lookless по природе как оно в WPF?
в авалонии да, а в формсах? а в формсах я должен все вручную.
Почему? Он меня нервирует.
В 90% случаев на шарпе пишется стандартный КРУД со стандартными гридами, и вся мощь луклеса нахуй не нужна. Нормальным, адекватным людям нахуй не нужны в быту круглые кнопки со встроенным калёндарём.
>Нормальным, адекватным людям нахуй не нужны в быту круглые кнопки со встроенным калёндарём.
Ой как же ты не прав. В текущей конторе - тоже так думали долго, пока конкуренты не сделали красивенько и более удобно, в результате - отжали дохуя клиентов, а эта контора потеряла просто дохуя денег.
Ну, рил. Миллионы долларов убытков, потому что сделали в 2001м приложуху, и просто добавляли в нее вичи по клиентам, когда приходили и говорили бизнесу, что ну, типа, надо ОСВЕЖИТЬ, люди говорят что уже в монстра превратилось и сложно даже простые вещи делать, а интерфейс времен XP вызывает отторжение у новых пользователей, че бизнес говорил: Да-да, это все конечно важно, но куда они денутся.
И появляется конкурент, который сделал то же самое, но красиво и выпилив тот функционал, который залетал и нужен был одному клиенту из 1000, и все - теперь конкурент получает эти миллионы денег, а бизнес кричит, что вы долбоебы, все просрали, вообще, надо было вчера сделать красиво и удобно, а вы такие растакие ебаньтяи.
Меня уволят, если я про нее напишу, няша. Но с вероятностью 95% у тебя в доме их прибор имеется.
> бизнес говорил: Да-да, это все конечно важно, но куда они денутся.
> риходили и говорили бизнесу, что ну, типа, надо ОСВЕЖИТЬ
> бизнес говорил: Да-да, это все конечно важно, но куда они денутся.
> теперь конкурент получает эти миллионы денег, а бизнес кричит, что вы долбоебы, все просрали
Охуительно кабан нашёл виноватых.
Вот именно поэтому я - индюк.
Какиони узнают что это ты написал?
Когда надо сделать простенький Api с минимумом логики. Например вернуть простую строку.
>Вот именно поэтому я - индюк.
Ну т.е. ты и кабан и исполнитель в одном лице. Т.е. в любом случае за свой проеб "кабан" будет винить "исполнителя"
Пасаны. Thread или Task ? И почему?
Бонусный раунд: когда вы вообще последний раз использовали Thread ? (Подразумевается не копание в каком-то легаси, а написание чего-то нового.)
Thread когда точно знаешь что тебе нужен Thread, Task когда ты задаёшься вопросом что выбрать Thread или Task.
![1711361008325.png](https://2ch.life/pr/thumb/3097760/17113610098470s.jpg)
Нахуя тебе райдер? Что конкретно в нём ты используешь в своей работе постоянно такое, что тебе не хватает бесплатной студии / бесплатного коде?
Он мне нахуй не нужен, мне нужен ReSharper, но это всё один пакет dotUltimate. Без решарпера студией пользоваться просто менее удобно, в нём куча всяких удобных гибких штук для кастомизации правил выравниваний, переносов, отступов и т.д. на каждый тип структур кода. Ну и человеческий Solution Wide Analysis, конечно же, без него в целом жить больно очень, как и без решарповского запускатора юнит-тестов.
В общем, это буквально база для работы над любым крупным проектом.
> база для работы над любым крупным проектом
Ну раз у тебя крупный проект, то пусть руководство и закупает.
> куча всяких удобных гибких штук для кастомизации
НЕНУЖОН
> Solution Wide Analysis
НАХУЙ
> запускатора юнит-тестов
ПЕРЕБЬЁШЬСЯ
Закупает где? Вот он и спрашивает про покупку
![20240109040934.png](https://2ch.life/pr/thumb/3097760/17114479642540s.jpg)
Проект на 7 дотнете, простой get который возвращает json в котором по сути самое жирное это картинки в base64 строках.
Сначала была ебическая просадка когда я доставал из базы EF'ом async'ами, в стековерфлоу сказали что это кривизна особенность реализации EF'а и потому нужно просто забить хуй и лучше доставать данные синхронно.
Сейчас в данном примере находится 4 картинки общим весом под 7МБ.
Само доставание из базы через EF и формирование json'а отрабатывает около секунды (область в stopwatch'е) (что вообщем-то тоже мне кажется дохуя, хотя я могу быть не прав). Это не первый запрос, потому все инициализировано, база ms-sql в локалхосте.
Вопрос следующий - почему у меня в локалхосте идет загрузка 7МБ - 10-13 секунд? То есть в дебагере сам метод в контролере какбэ отработал и дальше 10-13 секунд идет передача данных.
Что я делаю не так и как с этим совладать?
Или обязательно нужно делать отдельное апи которое будет возвращать Content-Type: Image? Но с загрузкой все равно какая-то нездоровая ебала.
Вообще меня сейчас волнует именно загрузка, а не запрос к бд.
> я просто на бесплатную лицензию EAP перешёл, которую постоянно сбрасывать можно и по новой активировать
Что и требовалось доказать. Жетбренсовский пиарщик бегает по российским форумам (и бордам) и прогревает гоев, что можно пока что бесплатно пользоваться.
> Главное, не забывайте нас
Как бы говорит нам жетбрейнсовский пиврщик.
Нахуй иди, нам и на вскоде норм.
> и на вскоде норм
Как сказать, что ты никогда в жизни не писал код на шарпе за деньги, не говоря о том, что ты никогда в жизни не писал код на шарпе за деньги.
Просто не пользуйся говном под названием EF. Эта хуйня как интернет эксплорер: никому нахуй не нужен, но майкрософт продолжает его везде проталкивать. Пиши sql руками, смотри план запроса, для маппинга используй dapper, а не это индусское говнецо.
У тебя одни деньги на уме. Капитализм совсем тебе моск съел. В жизни столько прекрасного, а ты думаешь о том как бы заработать еще больше денег. Выгляни в окно, посмотри какая погода, почки набухают, пчёлки жужжат.
Деньги, блять.
> Пиши sql руками
Надо же, как маятник истории покачнулся. 20 лет назад писали запросы руками, 10 лет назад конструировали конструкторами, а щас опять руками.
Ты же в курсе, как работает Skip и Take? Оно вытягивает на клиента все записи, а потом часть выбрасывает. Если у тебя 1000 строк и надо показать последние 20, из базы уедут все 1000. Пейджинг в бд делается через row_number over partition.
Запросы всегда писали и оптимизировали руками, это база. Не изобрели еще фреймворк, который умеет в запросы. Хибернейт в джаве появился еще до твоего рождения, но очему-то опытные разработчики по-прежнему пишут sql руками, угадай, почему.
Блять, еще один.
Повторяю еще раз -
>>100546
Во первых у меня буквально пока что буквально одна строка.
Во вторых (поправь меня если я несу хуйню) там IQueryable, и в конце идет ToList и запрос делается уже именно на нем насколько мне известно.
Повторяю еще раз, моя основная проблема сейчас это очень длинная загрузка небольшого json'а с апи (Content-Type: application/json; charset=utf-8), а не EF.
Посмотрите этот ебанутый 2 пик еще раз >>100360.
То есть, тормозит даже если ты просто возвращаешь фейковые данные, без запроса в бд?
Потому что удобно все сложить в единую логическую кучу, у меня связь в бд 1 к 1 + не нужно писать отдельное апи для пикч.
Тебе знакомо понятие "статический контент"? Про CDN слышал?
Я и не думаю что проблема на стороне моего кода, возможно я просто делаю это не таким образом как принято это делать.
Я понимаю что проблема на стороне асп, как и в случае с асинками в EF, вопрос - что мне делать и как это фиксить?
Да, и?
Что ты будешь делать если тебе нужно будет получить с апи другой контент или просто много текста? Будешь ждать 15 секунд для получения 7МБ?
Локализуй проблему.
Двачую этого. Решарпер умеет в адекватное форматирование кода, а именно: форматирование блоков инициализации массивов/списков.
Если бы студия умела, то решарпер был бы не нужен. А так... имеем, что имеем.
>в адекватное форматирование кода, а именно: форматирование блоков инициализации массивов/списков.
Покажи пример.
1. Сервис принимает два аргумнента: Id и дто
2. Сервис принимает один аккумулированный объект (переложить в другую модельку)
3. Сервис принимает один объект, содержащий Id, который присвоим в контроллере
https://pastebin.com/MJyTNeaM
Честно? От настроения)
Сейчас стараюсь делать вот так:
Сервис - принимает в себя Request<T1> и отдает Result<T2>
Result - это тип, который содержит либо ответ, либо ошибку с описанием ошибки.
Проблема такого подхода, что пришлось вводить Success если что-то в сервисе не возвращает какого-то объекат.
Обычно T1 - это та же DTO или расширенный объект, который содержит в себе DTO + что-то что там надо(id, токен авторизации, имя пользователя и прочая хуйня, которую можно извлечь из запроса)
Второй вариант. Задача контроллера - это принять данные, провалидировать их, проверить все пермишены, если все ок - вызвать сервис. У сервиса свои модели, его не должно ебать, как к тебе в апишку приходят данные.
> провалидировать их
Не задача контроллера.
Задача контроллера - принять запрос и передать его дальше.
Валидация - это часть бизнес-правил. Вот прилетел тебе запрос на пополнения баланса. Пополняют с несуществующего кошелька. Запрос, в плане бизнеса - невалидный. Если контроллер будет это валидировать, у тебя бизнес протек в контроллер. Если не будет - то у тебя размазана валидация по разным слоям. Тут мы провалидировали, а там - нет, не бред же, потом ищи-свищи, как хуйня попала сюда.
Так что если запрос уж дошел до контроллера, т.е. на его уровне - моделька валидна - он ниче не должен больше валидировать, а просто передать тому кто будет исполнять.
Валидация делается на всех уровнях. В контроллере проверяется, что у юзера есть пермишен вызывать этот эндпоинт. Посмотри, как сделано в амазоне, там 100500 ролей на каждую ручку и хуй ты что сделаешь без явного разрешения.
Правила бизнес-логики проверяются дальше, в самой логике, это очевидно. Речь о том, что контроллер принимает просто какие-то данные от пользователя, вообще любые данные, и должен их проверить прежде, чем отдавать дальше. Не должен пропустить всякие хитровыебаные инъекции. Должен обмазать все логами. Должен поймать и обрезать эксепшены, чтобы вместо полного колстека наружу уехала ошибка 500. Этим занимается слой контроллеров.
Так пермишины ты еще на уровне аутентификации до того как к контроллеру дело дойдет должен был проверить...
Как и валидность модельки - в ASP.NET - еще на уровне роутинга.
Так что остается валидировать-то в контроллере?
Плюс, эксепшны - это зло. Понимаю, почему люди их используют, но у нас на ревью - тебе бы долго пришлось доказывать реальную необходимость, вместо возвращения Error'а
Ты неироничто предлагаешь возвращать код ошибки вместо эксепшенов? 2024 год на дворе, не 1964.
На каком уровне находится проверка ролей. К тебе приехал токен, он валидный, nginx пропустил запрос на твой сервер, сервер вызвал контроллер. Где будет проверка?
Правильно, проверку делает фреймворк, тебе надо лишь расставить аттрибуты. Но проверка происходит все равно на уровне контроллеров. Если ты захочешь написать сервис скажем на ноде или на го, ты должен понимать, как все это работает под капотом.
https://github.com/josuelopezv/aDrums
(проект WebApp.ADrums)
На современной VS получилось только с помощью SDK 2.1 мигрировать проект в csproj (после миграции целевая платформа была заново обновлена до dotnet framework 4.8), но судя по всему забилдилось/мигрировалось криво, и при запуске оно не видит исходники страниц (.cshtml). При открытии страницы браузер писал, что нет доступа именно в странице, а в консоли выдавалось исключение об отсутствии исходных файлов (index.cshtml, но были и другие файлы). Помогите, аноны
https://github.com/josuelopezv/aDrums
(проект WebApp.ADrums)
На современной VS получилось только с помощью SDK 2.1 мигрировать проект в csproj (после миграции целевая платформа была заново обновлена до dotnet framework 4.8), но судя по всему забилдилось/мигрировалось криво, и при запуске оно не видит исходники страниц (.cshtml). При открытии страницы браузер писал, что нет доступа именно в странице, а в консоли выдавалось исключение об отсутствии исходных файлов (index.cshtml, но были и другие файлы). Помогите, аноны
![17114965909205804.webp](https://2ch.life/pr/thumb/3097760/17114967584600s.jpg)
https://www.thesunshinelayer.com/p/9-rules-for-writing-cleaner-code
Зависит.
Если надо быть уверенным, что какой-то кусок кода будет выполняться в фоне, и не хочется ебаться с планировщиками и контекстами синхронизации - то проще явно тред создать.
Допустим, какой-то watchdog программный, который должен ебнуть что-то, если что-то "зависло". С тасками такой вочдог - при скакнувшей нагрузке и дохуищах тяжелых операций - твой вочдог может вообще никогда не выполниться, или выполниться с таким опазданием, что ну его нахуй.
> Бонусный раунд: когда вы вообще последний раз использовали Thread ?
Буквально вчера.
Многие (большинство) пункты очень спорные.
Такой код может быть только в "идеальном" мире с "идеальной" предметной областью.
Как раз таки 2024-й год. Эксепшен - в лог, пользователю - читаемая ошибка. Эксепшены вообще не должны наружу просачиваться, с ними либо поддержка разбирается, либо юзер (если он продвинутый) идет в мониторинг/логи и разбирается.
А так обычная байда в стиле дяди Боба. Новичок в любом случае не поймет и только с километрами написанного своего и что важнее прочитанного/разобранного чужого кода научится это применять с толком. Опытный же будет до усеру доказывать, что тут все спорно и вот есть кейсы, когда "эти правила неудобны, поэтому они говно".
Вообще мимо ванга, сериализация идет меньше секунды.
Если поменять тип возвращаемых данных с контроллера с application/json к application/octet-stream время загрузки падает с 13 секунд до 33мс, как оно вообщем-то и должно быть.
Прикладываю нотариально заверенные фотокарточки.
Спасибо разработчикам асп!
Я хотел тебе предложить File вместо Ok, только использовать stream вместо byte[], но почему-то подумал, что тебе нужен json отправлять по факту и решил ничего не писать.
Мне какбэ и нужен json, но клиент по прежнему хавает и десериализирует без изменений кода, правда время десериализации увеличилось в несколько раз вероятно из-за того что там проебалсь разметка в виде отступов и переносов и весь текст идет одной кашей.
Сейчас погуглю как это пофиксить и буду дальше держать вас в курсе.
Какой пиздец
>>101596
Вероятно я таки буду делать отдельную таблицу+апи для изображений в который я буду складывать все изображения из всех таблиц и кидать на клиент гуид id изображений из которых затем клиент будет доставать отдельными запросами все пикчи. Я бы
Я бы хотел возможно даже сделать байт поля для пикч в этой же таблице, только я хз как это передать на клиент одним запросом при условии что у меня ботлнек в десериализации.
Или ещё проще храни в БД путь к файлу, а дальше
byte[] bytes = File.ReadAllBytes(path).
В теории можно использовать FileStream и сразу же его вернуть в контроллере.
>и кидать на клиент гуид id изображений из которых затем клиент будет доставать отдельными запросами все пикчи.
Почему ты так сразу не сделал? В том смысле, что метаданные отдаются отдельно, тело файла отдельно? Вроде бы всегда так делается.
Так я тебе писал, что дело в сериализации.
Напиши свою сериализацию под эту конкретную задачу, будет быстрее работать.
>через кастомные хедеры
А потом у тебя прокся их порежет или подменит и ты долго будешь искать "а где-же мои данные?..."
>Обёртка для коллекций?
Почему нет. Большинство коллекций итак по факту уже обертки над чем-то базовым вроде массива. Если у тебя над коллекцией постоянно применима какая-то доменная логика, либо тебе не нужен дохулион методов которые в ней есть, то вполне логично убрать её за какой-нибудь фасад.
Я дергал постманом. Нету разницы чем дергать.
Я согласен только с первыми двумя пунктами, остальное хуита уровня старая джава. Напишите охулиард классов по 10 строчек в каждом чтобы что? Прочитать два экрана кода это сложна нипанятна, а разобраться в 100500 одинаковых классов в 100500 файлах - это легко и просто.
Добро пожаловать в волшебный мир майкрософт, где каждая домохозяйка может написать свой сервер.
Следующий шаг - использовать dapper, а EF выбросить нахуй.
![камон контролс v6 манифест деда](https://2ch.life/pr/thumb/3097760/17115546269890s.jpg)
Я сегодня весь рабочий день занимался написанием сравнительных двух проектов под мою задачу, а задача у меня: трей-приложение, висящее в трее и открывающее формочки из своего контекстного меню, при закрытии формочек, они не выгружаются, а скрываются (т.н. "сворачивание в трей"). Я люблю такие утилиты с давних пор.
Так вот. Практика показала, что в Авалонии такое приложение написать легче, и требуется меньше бойлерплейта. В Ето.формсах приходится полностью описывать настройку трей-иконки, её включение и выключение производить вручную, иначе при закрытии приложения иконка не удаляется из трея. Исчезает при наведении мышки, как будто приложение аварийно завершилось. В Авалонии же достаточно один раз описать в богомерзком хамле трей меню, добавить бинды команд и радоваться. Удаление иконки производится автоматически лайфтаймом. Скрытие и показ - по желанию.
По саппорту тоже всё намного лучше у Авалонии, 5 сек в гугле и я выяснил, как запустить приложение в трее, без формы, и как отложенно подгрузить форму по команде. У Ето.формс с этим огромные проблемы, поскольку он юзается в основном для написания аддонов для этого ихнего рино, то вся поддержка касается исключительно этого, по любым смежным вопросам обсуждений ноль, готовых решений ноль.
Единственное, что огорчает, отсутствие нативной темы. Я понимаю, что отстал от моды и в моде опять разноцветные свистоперделки с фирменным стилем. Хорошо, я знаю, что можно сделать свистоперделочный флюент, выглядящий пиксель в пиксель одинаково на винде и в линуксе, но мне пох, дайте мне нативную тему. Кекекс, ты меня слышишь? Как на пикрелейтеде тему хочу.
если бы только не шрифты и мыло мыыыло
Ок. Давай разбирать.
> Use Only One Level of Indentation per Method
Хуета.
Во-первых, таким хуем у тебя просто появляются методы/функции, которые нахуй не упали, кроме как исполнить это правило.
Во-вторых, на ревью, когда правится будет в вынесеном методе - ты заебешься искать, а че же и нахуя поменялось.
В-третьих, по опыту - такой код труднее поддерживать и сопровождать.
> Don’t Use the ELSE Keyword
Хуета.
Во-первых. Очень часто - оно реально надо, без него - получаются монструозные конструкции, просто чтобы избежать.
Во-вторых. Не просто так его придумали. Было бы не нужно - выпилили бы.
> Wrap All Primitives and Strings
МЕГАХУЙНЯ.
Просто ПИЗДЕЦ КАКАЯ ХУЙНЯ.
Во-первых. Ты из-за этого чтобы ОРМ какую-нибудь подружить с этой хуйней - должен высрать киллотоны бойлерплейта, чтобы потом оказалось, что надо чет поменять - и ты высрал еще больше бойлерплейта.
Во-вторых. Тебе такое спасибо скажут те кто будут это сопровождать, что никаких денег не хватит чтобы всего зашить.
В-третьих, абстракция ради абстракции.
> Use First-Class Collections
Аналогично предыдущему пункту.
> Use Only One Dot per Line
Хороший совет, в контексте - когда не обойтись иначе.
> Don’t Abbreviate
Спорно. Во многих случаях есть аббривиатуры, типа temp, ctx и прочее, которые все понимают. Опять же, если делаете в контексте предметной области - там бывают свои сокращения, которые удобны бизнесу, и никто не помнит как оно полностью произносится.
Но в общем случае - согласен.
> Keep All Entities Small
Хуета. Особенно как там показано.
Ты потом заебешься разбираться в этой груде файликов.
> Don’t Use Classes with More Than Two Instance Variables
МАГАХУЙНЯ
Просто пиздец какая.
Даже объяснять лень.
> Don’t Use Getters or Setters
МЕГАХУЙНЯ
Просто пиздец какая.
Но тут я объясню.
Во-первых, их не просто так придумали. Миллилард случаев, когда это надо и удобно.
Во-вторых, то что предлагается взамен - это тот же геттер-сеттер, просто названый иначе. Чтобы что? Чтобы потенциального противника запутать? Чи шо? Чи зачем?
> Don’t Use Comments to Justify Bad Code
ДА! Охуенно будет посмотреть, как эта хуйня будет разбираться в коде джуна, который почитал этих советов и пошел хуярить. Посмотрю, как оно будет чет там делать в проекте, который писали деды, у которых первым языком были плюсы и они до сих пор пишут как на си. Посмотрю, как оно будет в предметной области разбираться, про которую нихуя не знает.
Короче. По большей части - какой-то сборник вредных советов. Ну или гайд, как писать много нахуй никому не всравшегося кода, который никто не сможет поддерживать.
Ок. Давай разбирать.
> Use Only One Level of Indentation per Method
Хуета.
Во-первых, таким хуем у тебя просто появляются методы/функции, которые нахуй не упали, кроме как исполнить это правило.
Во-вторых, на ревью, когда правится будет в вынесеном методе - ты заебешься искать, а че же и нахуя поменялось.
В-третьих, по опыту - такой код труднее поддерживать и сопровождать.
> Don’t Use the ELSE Keyword
Хуета.
Во-первых. Очень часто - оно реально надо, без него - получаются монструозные конструкции, просто чтобы избежать.
Во-вторых. Не просто так его придумали. Было бы не нужно - выпилили бы.
> Wrap All Primitives and Strings
МЕГАХУЙНЯ.
Просто ПИЗДЕЦ КАКАЯ ХУЙНЯ.
Во-первых. Ты из-за этого чтобы ОРМ какую-нибудь подружить с этой хуйней - должен высрать киллотоны бойлерплейта, чтобы потом оказалось, что надо чет поменять - и ты высрал еще больше бойлерплейта.
Во-вторых. Тебе такое спасибо скажут те кто будут это сопровождать, что никаких денег не хватит чтобы всего зашить.
В-третьих, абстракция ради абстракции.
> Use First-Class Collections
Аналогично предыдущему пункту.
> Use Only One Dot per Line
Хороший совет, в контексте - когда не обойтись иначе.
> Don’t Abbreviate
Спорно. Во многих случаях есть аббривиатуры, типа temp, ctx и прочее, которые все понимают. Опять же, если делаете в контексте предметной области - там бывают свои сокращения, которые удобны бизнесу, и никто не помнит как оно полностью произносится.
Но в общем случае - согласен.
> Keep All Entities Small
Хуета. Особенно как там показано.
Ты потом заебешься разбираться в этой груде файликов.
> Don’t Use Classes with More Than Two Instance Variables
МАГАХУЙНЯ
Просто пиздец какая.
Даже объяснять лень.
> Don’t Use Getters or Setters
МЕГАХУЙНЯ
Просто пиздец какая.
Но тут я объясню.
Во-первых, их не просто так придумали. Миллилард случаев, когда это надо и удобно.
Во-вторых, то что предлагается взамен - это тот же геттер-сеттер, просто названый иначе. Чтобы что? Чтобы потенциального противника запутать? Чи шо? Чи зачем?
> Don’t Use Comments to Justify Bad Code
ДА! Охуенно будет посмотреть, как эта хуйня будет разбираться в коде джуна, который почитал этих советов и пошел хуярить. Посмотрю, как оно будет чет там делать в проекте, который писали деды, у которых первым языком были плюсы и они до сих пор пишут как на си. Посмотрю, как оно будет в предметной области разбираться, про которую нихуя не знает.
Короче. По большей части - какой-то сборник вредных советов. Ну или гайд, как писать много нахуй никому не всравшегося кода, который никто не сможет поддерживать.
Настя??
Репорт.
Одновременно ностальгические и вьетнамские флешбеки.
Хочу простым и элегантным методом узнать не выхожу ли я за рамки.
Так что б в одну строчку, как если бы IndexOf работал с многомерным массивом.
Вот например
int[,] mass = new int [2,2];
и я пикаю позицию 10,10 через какой-ниубдь встроенный метод и получаю сообщение пошёл нахуй ты куда лезешь.
что б никаких обработок исключений, или подобной хуеты.
хотя тут две задачи, узнать нициализирован ли и не выхожу ли я за рамки размера массива.
![image.png](https://2ch.life/pr/thumb/3097760/17116310031600s.jpg)
Делаю BulkInsert по 1к записей List Но почему то скипаются ид и не идут по порядку. Почему так? Записей столько же сколько и в файле, 9500. Тоесть записи сами не теряются, теряется порядок в присвоении ID/
Может у тебя в сиквенсах какая-нибудь логика или их еще кто-нибудь дергает.
А так-то вообще обычно похуй на их порядок совершенно.
Да ничего вроде нету, топу добавляю список, и скипает каждый раз в одном месте, в EF всё норм.
![image.png](https://2ch.life/pr/thumb/3097760/17116480807630s.jpg)
Да там и кода то нет
Просто заполнение List элементами, когда их 10к добавляем в бд и очищаем список. EF вставляет нормально через AddRange.
Причём проебываеться всегда в том месте где на скрине, и если у всех записей id = 0 и если я сам делаю id +1 по порядку.
Фикс, это я просто переименовал в MasterDataList, просто в закоменченой строке старое название осталось.
Ну как не знает если он нормально вставляет но проебываеться почему то в одном месте? Пребывает именно порядок присвоения ID, сущности не проебывает.
Ид заполняется в бд и возращается после вставки. Кури как работает инкремент в колонке.
А вообще включи просто логи запросов
![qes.png](https://2ch.life/pr/thumb/3097760/17116500091220s.jpg)
Парни такой вопрос.
Эксперементировал с инструкцией goto и у меня возник затуп.
На пикриле мой код который считает до ста тыщ и когда закладка Ass была после строки int a = 5, то всё было норм.
Но я сейчас переставил закладку до инициации переменной и НИХУЯ НЕ ИЗМЕНИЛОСЬ. Код всё ещё работает каким то хуем и считает до ста тыщ, хотя не должен, ибо каждый цыкл, переменная а = 5, в конце увеличивается до 6, но после goto она заново инициируется как 5. И так снова и снова. 5656565656 как блядь она до ста тыщ считает? Чё за параша?
Как это говно работает? Почему значение переменной сохраняется?
Я дебил, забираю свой вопрос назад, как только запостил свой высер так сразу просёк в чём суть.
Не стать мне программистом походу, я слишком дэбилен.
Бля, сидел минут 5 пырил в твой код не мог понять что там вообще происходит.
Дийкстра был прав про goto.
Ну если сам дтшёл, то в чём проблема? Ты уже программист. Только не используй goto пока не постигнешь Дао. Его можно использовать только опытным программистам, которые понимают когда он нужен.
>Ещё раз. Почему ты решил, что порядок столбцов для Dapper'а неверный?
Потому что не нормально когда добавляешь 1к записей в пустую бд и ID пишется с пропусками 1 2 3....200 ХУЯК 250 251 252. В EF так не происходит, 1к записей добавляется все ID пишутся от 1 до 1000
![2024-03-2822-08-56.png](https://2ch.life/pr/thumb/3097760/17116532462170s.jpg)
- По какой-то причине дескритор окна возвращает Zero, хотя окно браузера визуально загрузилось.
- Еще process.HasExited == True
- Попытка получить новый экземпляр процесса по айди текущего Process.GetProcessById(process.Id) вызывает исключение, мол процесс не загружен.
Что не так?
Ты не поверишь, но всем везде абсолютно похуй, в каком порядке вставит записи в бд. Тем более через какой-то булк инсерт, что это за хуйня вообще?
Потому что стартап процесс уничтожается сразу. Хромиум ёпта
Ну клиенту не похуй. Мне так то тоже похуй в каком там порядке, хоть с прыжками в 1к
>>101009
> Сервис - принимает в себя Request<T1> и отдает Result<T2>
> Result - это тип, который содержит либо ответ, либо ошибку с описанием ошибки.
> Обычно T1 - это та же DTO или расширенный объект, который содержит в себе DTO + что-то что там надо(id, токен авторизации, имя пользователя и прочая хуйня, которую можно извлечь из запроса)
Получается, что это второй вариант.
Как я понимаю, при втором варианте придётся отказываться от автоматической валидации и валидировать модельку в ручную?
builder.Services.Configure<ApiBehaviorOptions>(x => x.SuppressModelStateInvalidFilter = true);
Что используешь в качестве валидации: прокидываешь ModelState или FluentValidation?
Можешь показать пример с монадой и централизованной обработкой ошибок (формирование ответа клиенту)?
> Второй вариант.
Получается как-то так:
https://pastebin.com/hiMPRSGu
Но смущает, что будет много однотипных моделек, которые будут минимально различаться. И это только одна моделька с двумя свойствами.
Как бороться с однотипным неймингом? Никак
Какой стиль именование общепринят?
>>101045
> Плюс, эксепшны - это зло. Понимаю, почему люди их используют, но у нас на ревью - тебе бы долго пришлось доказывать реальную необходимость, вместо возвращения Error'а
Что не так с исключениями? Их всё равно надо ловить и формировать ответ клиенту.
>Можешь показать пример с монадой и централизованной обработкой ошибок (формирование ответа клиенту)?
У меня это что-то в духе:
Task<Response> Foo(SomeDTO requestData) {
// упрощенно, в реальности, там екстеншн, который все мапит как надо
return service.Handle(new Request(requestData, User.GetUserData()))
.Match(
success => Ok(success.Payload),
error => CreateFancyErrorResponse(error);
)};
Эксепшины, как я сказал - я не кидаю. Иногда - ловлю. Сам я возвращаю Error.
В коде сервиса это выглядит так:
// упрощенно
public Result<Some> Handle(Request<Some> request){
try{
var result = DoSomeBuisnesLogic(request);
return result;
}
catch{}
return new Error();
}
Почему так? Потому что так удобнее.
Про валидацию - та что нужна в качестве проверки валидности JSON'чика/XML'ки - происходит на уровне мидлварей. Ну, там, что не null, что вместо числа не прислали строку.
Та что нужна на уровне бизнеса - с помощью валидатора вида:
Rulleset<User>
.For(x=>x.Name)
.Min(2)
.Max(128)
,For(x=>x.Email)
.IsEmail()
.For(x=>x.Age)
.Min(21)
.Create();
"Эта хуйня биндится либо к модели вцелом, либо к эндпоинту и так же при валидации возвращает ошибку валидации.
>Можешь показать пример с монадой и централизованной обработкой ошибок (формирование ответа клиенту)?
У меня это что-то в духе:
Task<Response> Foo(SomeDTO requestData) {
// упрощенно, в реальности, там екстеншн, который все мапит как надо
return service.Handle(new Request(requestData, User.GetUserData()))
.Match(
success => Ok(success.Payload),
error => CreateFancyErrorResponse(error);
)};
Эксепшины, как я сказал - я не кидаю. Иногда - ловлю. Сам я возвращаю Error.
В коде сервиса это выглядит так:
// упрощенно
public Result<Some> Handle(Request<Some> request){
try{
var result = DoSomeBuisnesLogic(request);
return result;
}
catch{}
return new Error();
}
Почему так? Потому что так удобнее.
Про валидацию - та что нужна в качестве проверки валидности JSON'чика/XML'ки - происходит на уровне мидлварей. Ну, там, что не null, что вместо числа не прислали строку.
Та что нужна на уровне бизнеса - с помощью валидатора вида:
Rulleset<User>
.For(x=>x.Name)
.Min(2)
.Max(128)
,For(x=>x.Email)
.IsEmail()
.For(x=>x.Age)
.Min(21)
.Create();
"Эта хуйня биндится либо к модели вцелом, либо к эндпоинту и так же при валидации возвращает ошибку валидации.
У тебя фп головного мозга.
Я раньше думал, что операторы типа && работают так:
если выражение слева неверное, то выражение справа даже проверять не будет.
Разве не так всегда было? А у меня и выражение слева и выражение справа выполняется, хотя выражение слева неверное..
например
if( 2 < 1 && 2 < 3)
разве после проверки выражения слева не должно пойти выполнение в элсе?
if( x < massive.GetLength && massive.GetLength[x] !=0 )
и я получаю мессагу, что вышел за пределы, хотя выражение слева и должно было бы проверить это сука. Схуяли выражение справа всё равно выполняется?
Как я понял, такие выражения рассчитываются при компиляции.
самый умный да?
нахуй ты сюда ныть пришёл?
Если допустить, что ты не троллишь тупостью и сам себя не объебываешь (например у тебя в реале там просто &, а не &&),
то чтобы понять где косяк, раздели для отладки выражение на два (через два if-а например) и посмотри реально ли они там у тебя выполняются так как ты хочешь. Судя по виду у тебя там какие-то кастомные методы и вполне может быть что выражение x < massive.GetLength выдает тебе true, когда ты ожидаешь false, просто потому что ты где-то в .GetLength объебался.
Зачем нужен интернет эксплорер вместо браузера? Зачем нужен team foundaton вместо гита? Индусы имитируют бурную деятельность you know, чтобы их не разогнали к хуям.
Ни один человек в мире не пишет хай перфоманс вычисления на дотнете, это база. Можно сколько угодно выебываться экономией в 20 наносекунд на манятестах, но в реальности приходит сборщик мусора и наступает пиздец. В реальном коде на сишарпе даже Dictionary используется примерно никогда, в 99.99999% случаев достаточно обычного List.
Когда ты найдешь свою первую работу, убедишься сам. Задачки с литкода - это не программирование за деньги.
Дебилы, блять, нихуя не читают:
>instances are optimized for situations where the same set of values is frequently used for searching
>used for
Ты должен использовать SearchValues<T> в методах MemoryExtensions:
https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions?view=net-8.0
https://devblogs.microsoft.com/dotnet/performance-improvements-in-net-8/#searchvalues
Джуник, спок. Чем эта новая хуита отличается от хэшсета? В каких задачах ты будешь использовать эту хуиту? Кто вообще, блять, пишет числодробилки на дотнете, покажите этого ебанутого.
Алсо
>ссылки на официальную пропаганду от микрософт
Дурачок ты у мамы.
>пишет числодробилки на дотнете
во первых, это поиск в строке
во вторых ты, дурачок мамковый, часто САМ пишешь реализацию поиска в строке руками? Иначе куда твой хешсет присунуть?
ну если да, то жаль тебя, очень жаль.
Поридж, поиск в строке в дотнете написан еще до твоего рождения. Речь о том, что вся эта тема со спанами и SearchValues нахуй не нужна на практике. Это классическая имитация бурной деятельности.
ТЕБЕ не нужна, ОХОТНО ВЕРЮ
по тебе прямо видно.
нормальным людям вполне себе нужна
И поиск конечно написан, что его там искать. Например твой тупой поиск через HashSet. Но если бы ты немного бы был умнее, то знал, что часто можно улучшить и то что "вроде бы быстрое"
Для НЕУЧЕЙ поясню что вот есть утебя допустим база данных. Она быстрая конечно, но все равно весьма долгая. И УМНЫЕ люди (но не ты конечно) могут влепить перед ней фильтр блума, который в сотни раз быстрее
Так вот даже твой быстрый HashSet все равно медленнее битового фильтра блума - раз. Более того, можно посмотреть что все значения они ASCII и тогда переключиться на другой алгоритм сравнения.
Но тебе не нужно, ты и не юзай. Оставайся формошлепом. А эти вещи для тех, кто знает зачем оно им.
Проиграл в голос.
Та хуй знает. Конкретно с дикшинари - он же просто удобнее в куче случаев.
Ну, допустим, у тебя есть список сессий активных. У сессий - айди.
Тебе удобнее будет просто _sessions[id] и чет сделать, чем каждый раз как дебил искать ее в листе.
Вопрос не в перформансе а тупо в удобстве.
>>106476
>>106333
>Ни один человек в мире не пишет хай перфоманс
>Кто вообще, блять, пишет числодробилки на дотнете
>имитация бурной деятельности
Что за форс обиженного на шарпы? Нормальный код на шарпе насколько медленнее с++? На 2-15% в зависимости от задачи.
В нормальном перформансном коде на шарпе GC вызывается от 0 до 2 раз за всё время выполнения. А у криворуких конечно GC будет запотевшим и замотанным.
Спаны, натив мемори, интринсики, мемори-буферы, векторые операции, ансейф касты и прочие красоты позволяют эффективно писать быстрый красивый код на шарпе, а не код-урод на мерзких плюсах.
По моему в бафферс пакете ещё и avx прямо юзают
> В нормальном перформансном коде на шарпе GC вызывается от 0 до 2 раз за всё время выполнения
Кестрел, я так понимаю - не нормальный и не перформанс?
Потому что если попробовать на нем стресстест с эхо-хенделром 10к+ соединений и мгновенных отключений - ГЦ нехерово так ебется.
Или шо?
Вот на C объявляем указатель, выделяем память, присваиваем зачение, инкрементируем на + 1, выделяем память, присваиваем значение, и вот у нас уже массив динамический получился, с помощью free можем его освободить.
Может кто пример на C# такой же привести?
Дрочи указатели и память в unsafe секциях вот только за такое обоссать могут
C# под unsafe является надмножеством языка С.
Ну и где ты тут увидел динамический массив при аллокации определённого размера памяти я не понял
Во-первых, сессии лежат в редисе.
Во-вторых, пишешь FirstOrDefault и все работает.
В-третьих, enjoy your KeyNotFoundException.
Если уж нужно опускаться до заката солнца вручную, то в шарпе основная рыба обитает в районе классов MemoryMarshal, Native, Unsafe
прежде чем переходить к реальному unsafe
Под динамическим массивом имел ввиду динамическое выделение памяти. То есть массив с нефиксированной длинной.
У тебя неправильные тесты. Надо писать правильные, где раньше какой-то абстранктый кусочек кода выполнялся за 20 наносекунд, а с новой фичей за 10 наносекунд, двухкратный прирост прозводительности!!!11
И всё равно ты выделяешь сразу кусок памяти который уже потом заполняешь или нет. Это сорт оф лист только лист ещё и имеет функциональность на случай если выделенный размер кончился
Таких буферов не существует. Ты никак не сможешь гарантировать, что после первых 100 байт будет место для следующих 100 байт. У или все данные лежат рядом, но требуют копирования при увеличении размера контейнера как в листе, или данные лежат в блоках, как в хештаблице.
Как вариант можно хранить в начале блока его размер и ссылку на следующий, но это уже будет нихуя не массив с константным доступом
Будет О(1): ты сначал берешь остаток от деления индекса на размер блока, а потом этот остаток используешь как индекс в блоке. Задачка уровня easy на литкоде. Другой вопрос - зачем тебе такой контейнер?
Для таких хитровыебаных контейнеров надо открывать справочник по алгоритмам и смотреть варианты.
почему с помощью указателей? я бы понял если бы хотелось иметь унифицированный доступ к буфферу или chunkedbuffer
типа есть вот как MemoryStream, а есть ChunkedMemoryStream с тем же апи (который конечно же мелкие сделали internal, а наружу выдали другую реализацию брр)
или вот для спанов есть ReadOnlySequence, но это же просто враппер.
передать куда то где ждут указатель? но тут извините.
>MemoryMarshal, Native, Unsafe
>прежде чем переходить к реальному unsafe
А что ты подразумеваешь под "реальным unsafe"? Keyword (указатели и другая мелочёвка)? Просто перечисленные API также небезопасны.
небезопасен только Unsafe.
А реальный ансейф это когда ты *void во все поля без оберток более высокого уровня типа того же Unsafe
>А реальный ансейф это когда ты *void во все поля без оберток более высокого уровня типа того же Unsafe
Понял
>небезопасен только Unsafe.
Ну например, MemoryMarshal.CreateSpan() позволяет создать спан с отрицательной длинной, что может привести к неожиданным результатам, т.к. JIT считает что Length неотрицателен (у спанов, строк и массивов):
https://sharplab.io/#v2:EYLgxg9gTgpgtADwGwBYA0AXEUCuA7AHwAEAmARgFgAoIgBgAIiyA6AJXwwEsBbGZgSTwYYUCAAcAyiIBunMDADOAbmrUiKegFkAFKxgBDACYB5PABsAnhLH68AHk5CAfPX0BKagG9q9X4zIAnNoAJABEnvrMADIweADmGAAWAL4A9BoAvPQR0bEJifSp9CjJoW4qVMnUekamlta2Ds6u9FkA2vRkaPQk3QDM3RoAuhU67qPamjDc0Baa+lAKifpmzADCsPrCDXjasABmWtOz84vLqwDiMBh6+yKx8tru3XAobuVAA==
Ну и что сами разрабы дотнета думают:
https://github.com/dotnet/csharplang/discussions/6304
>Expose a concept of "unsafe callers only"
>The .NET Libraries would then be able to utilize this functionality on APIs such as System.Runtime.CompilerServices.Unsafe, System.Runtime.InteropServices.CollectionsMarshal, System.Runtime.InteropServices.MemoryMarshal, and System.Runtime.InteropServices.Marshal (subject to API review and approval).
И другие ссылки:
Enumerating type safety guarantees in MemoryMarshal and friends
https://github.com/dotnet/runtime/issues/41418
Add [CallerMustBeUnsafe] attribute to denote APIs which should be called in an unsafe block
https://github.com/dotnet/runtime/issues/31354
и ещё (один из разрабов):
https://www.reddit.com/r/csharp/comments/tqit91/comment/i2i8utl/
>Likewise, you don't always have to use the unsafe keyword to be doing something unsafe.
>Many of the APIs under System.Runtime.CompilerServices and System.Runtime.InteropServices are likewise "unsafe" and can easily cause undefined behavior, crashes, etc.
>The same goes for various other APIs scattered throughout the BCL, although we generally try to put Unsafe or another common "unsafe" related word (like Marshal) in the name.
Я кодирую в вс-коде на венде, но периодически сношу венду и перехожу на линукс и там продолжаю в том же коде, он в линуксе называется oss-code.
> дотнет для работы
Где на галере скажут кодить - там и будешь кодить.
>Где на галере скажут кодить - там и будешь кодить.
Говорят где хочешь. Да и не в том положении чтобы диктовать мне где кодить.
Не знаю, тут выше фанат решарпера неоднократно говорил, что без решарпееровского функционала невозможно успешно грести на галере. Я-то индюк, я не знаю.
До прихода всл я миксовал дебиан и винду, когда добавился сабж (а далее всл2) то на рабочей станции только винда стоит. С линью всё прекрасно пока её не пытаешься использовать как ос для пк.
>>106989
С ходу бросается в глазах расширенный рефакторинг и анализ всего солюшена, из не самого очевидного это тест раннер, оптимизация сборки, снипеты, интелисенс, дебаг тайм плюшки.
Если бы в идее был интерфейс студии то я бы не мучая себя пересел
Похуй, только учитывай, что VS по факту стандарт (просто потому, что чисто статистически он у большего числа разрабов) и твой код должен собираться именно в студии без всяких плясок с бубуном. Я не раз попадал в ситуацию, когда мне скидывали код который "Бля буду - у меня в райдере все билдится и запускается", в VS при открытии расцветал красным из-за того, что там что-то не так слинковано было или какие-либо анализаторы не подключены или еще из-за какой-то хрени.
![1711826274759.png](https://2ch.life/pr/thumb/3097760/17118262760370s.jpg)
Как же я ненавижу вереницы if - else if!
Как же хорошо, что в шарпе завезли свич-выражения с паттерн-матчингом. Вот, взгляните. Можно ли сделать ещё короче?
Возможность выбора. Но суть не в этом. Суть в том, что вы сами насрали в наш тред про то, что либ мало, а оказалось, что в 8 раз больше.
Допустим, у меня какая-то долгая таска. Она состоит из подтасок.
И я хочу иметь возможность отменить все это дело целиком, если что-то в течении какого-то времени не дергалось.
На текущий момент, я делаю во всех подтасках дерганье метода специального, типа: сказать, что я еще живой. И в отдельном треде - в цикле проверяю, когда дергалось последний раз, если больше нужного мне таймаута - клацаю CancellationTokenSource.
Но это же выглядит как хуйня страшная. А как нормально сделать - я чет не придумал.
Задача в принципе звучит как залупа. Таска запустилась, выполнила свою часть работы, вернула результат
И че мне делать, если таска "зависла"? Ждать вечно? Хуйня. Если по таймауту просто грохать - тоже хуйня, потому что это может быть таска, которая просто ДОЛГО выполняется, но если таки ДОЛГО подождать - она выполнится.
Нужен механизм, который наверх подаст сигнал: я еще живой, не убивай меня. А если не подаст - сверху грохнуть.
Ну вот пускай она сама и менеджит что делает и выжидает таймауты. Ты же когда делаешь условный запрос на апиху не дежуришь рядом поглядывая "а не висит ли запрос N секунд. О, не поставлен флажок уже 5 сек, пора прибивать", а просто пишешь эвэйт и ждёшь результат или исключение (в т.ч. таймаут)
>>107380
Смотри.
У меня есть устройства, доступные по УДП.
Есть задачи их опросить.
Бывает, иногда, что запрос - теряется. Но сверху - я не могу это понять. Со стороны таски - все нормально, она послала запрос - ждет ответ. Ответ может прилететь, а может не прилететь, а может прилетать частями. Код который обрабатывает ожидание ответа - я не контролирую, я только могу сверху передать CancellationToken, чтобы отменить все разом. Но когда что-то прилетает - триггерится эвент: received.
Так вот. Если запрос теряется - задача - будет висеть вечно. Если запрос - прилетает частями - а я буду убивать по таймауту, я потеряю то, что возможно таки собралось бы в нормальный ответ.
Меня просто смущает, что решение нихуя не элегантное и красивое. Я хотел бы что-то типа совмещения CancellationTokenSource с таймаутом и автоматического сброса таймаута по событию. Типа другой тип токена, который так же как обычный CancellationTokenSource но можно было бы подписаться на событие и сбрасывать таймер ожидания.
Не тупи. Ты в MainTask() вызываешь MakeUdpRequest(ct) внутри которого
var timeout = 30sec;
var rCt = creating linked cts with ct+timeout
await SendRequest(rCt);
await GetResponse(rCt);
Если почему то методы отправки и получения не могут в отмену то просто кастуешь await WhenAny(ReceiveTask, TimeoutTask)
Срсли. Если бы все было так просто - то я бы не спрашивал.
У меня есть сторонняя библиотека.
Дальше, дергается вот так:
device.Init();
device.Receive += onRecieve;
device.Send += onSend;
await device.Start(ct);
await device.ReadData(dataArray, ct);
И вот это вот ReadData - может зависнуть. Эту библиотеку я не контролирую, при этом не могу использовать другую, потому что других под работу с этими устройствами - нету.
Вот идеальным было бы решение в духе:
device.Receive += (s, e) => ct.ResetTimout();
device.Send += (s,e) => ct.ResetTimout();
Но как так сделать - я не знаю. CancellationTokenSource только либо отменяться умеет, либо принять таймаут и отмениться по нему.
Потому - я и нагородил вот эту вот фигню с циклом и если долго ни пришло и не отправилось - отменяю в этом цикле. А хотелось бы как-то красивше.
Почему ты не хочешь отменять ReadData по таймауту? Если метод не выполнился за 30 значит завис и отменится по комбиненому токену.
While not cancelled
Await ReadData(ct with 30sec timeout)
Done
> device.Receive += (s, e) => ct.ResetTimout();
> device.Send += (s,e) => ct.ResetTimout();
Не разделяю метод но под него можно написать класс внутри которого в цикле будет task.delay после завершения делея без cancelledEx будет отменён токен который ты везде передаешь и выход из цикла, а ResetWatchdog будет дёргать отмену task.delay тем самым не давая дойти до шага отмены твоего основного токена
таймеры никто не запрещал. Все просто же.
Проблема твоего кода, то что ты из таски пытаешься сделать что-то другое.
Task просто выполняет метод до конца. Всё. Логика работы метода - это не задача тасок.
![image.png](https://2ch.life/pr/thumb/3097760/17118814385910s.jpg)
Пытаюсь получить приватное поле у класса с дженериком, но даже просто копипаста кода из примера с learn.microsoft.com не работает.
Притом что без дженериков все примеры работают.
А вот вызов метода выделенного на пикриле всегда вызывает BadImageFormatException. Даже полная копипаста примера майков вызывает исключение.
Версия дот.нет - 8, студия последняя.
можно: все имена переменных однобуквенными сделай и удали все пробелы и отступы, чтоб все увидели, что ты сеньор девелопер
Работа такая донная что там это не используется от слова совсем, но на собесах постоянно спрашивают
Воу-воу, сеньоры наоборот пишут многобуквенные имена, чтобы все вокруг видели, как они высоки:
> ISeniorDeveloperDerivedInterface<IWeryMuchSmart> SeniorDeveloperFactoryObjectInstance
И комменты, тысячи их, а то ж юзеры тупые, не поймут, что до инициализации фреймворка, ничего не заработает.
И непременно лямбдами изъебнись. А то не примут в сеньоры.
>И непременно лямбдами изъебнись.
Ты смеешься но после "изъебывания лямбдами" смотреть на обычный мартышечный код неприятно, не то что работать с ним.
Двачую, я вот на ревью как престарелый дев думал зачем создавать лямбду прямо по среди функции и тут же вызывать ее в этом же скоупе, это ведь то что обычные функции делают? А оказалось это не модно уже.
>.NET Plus
>Компания сообщила, что запустит подписку .NET Plus для поддержки контрибьюторов и экосистемы .NET.
>Отключение текстовой рекламы в output при сборке проекта компилятором (без подписки возможен показ при сборке в режиме Debug)
>NFT - каждому подписчику будет доступна для минта SouldBound NFT в сети Ethereum. Коллекция будет посвящена новой вехе развития .NET и будет выпущена в ограниченном количестве. Известно, что владельцам NFT будут доступны некоторые привилегии, например, пожизненная скидка на подписку на продукты экосистемы .NET.
.NET - скам, теперь официально
Чулочки в комплекте?
> зачем создавать лямбду прямо по среди функции и тут же вызывать ее в этом же скоупе
Я надеюсь, мне только показалось, или ты действительно считаешь лямбдой всё, что содержит в себе символы => ?
Так вот, если мне не показалось, то нет, не всё со стрелочкой это лямбда в шарпе. Иногда это просто элемент синтаксиса, как в паттерн-матчинге на пикче выше.
Не, код на пикче страшнее смерти конечно, но речь не о нем, я говорил об абстракном изъебывании лямбдами
Чуток с опозданием, но всё же.
> Эксепшины, как я сказал - я не кидаю. Иногда - ловлю. Сам я возвращаю Error.
А какой смысл кидать "чистые" эксепшены?
У меня сейчас домен/сервис кидает эксепшен, но в фильтре его ловлю и возвращаю ErrorViewModel.
Какую библиотеку для фп используешь?
![image.png](https://2ch.life/pr/thumb/3097760/17119984403450s.jpg)
Точно. Но и кортеж не получается. Выдаёт ошибку.
> Других вариантов нет?
Есть.
Изменения в таблицу вносишь специальным методом базы данных (коммит). Пока изменения не внесены, в таблице данные измененные. Но когда коммитишь, они обновляются. Везде. Кроте тех таблиц, которые сами в состоянии редактирования.
Если же ты хочешь хранить две версии данных, то да, ты всё правильно понял. Одна тадлица - один набор данных. Хочешь другой? Делай другую таблицу.
>По факту, один объект может быть одновременно лежать в нескольких таблицах. При всём при этом, я хочу, например, чтобы какое-то поле объекта в разных таблицах имело разные значение. Скажем, в одной таблице поле age у этого объекта равно 21, а в другой 25
Звучит как какой-то архитектурный пиздец.
![234234234.png](https://2ch.life/pr/thumb/3097760/17120771293770s.jpg)
На пикриле код моей слот-машины и при написании этой параши у меня возникли два вопроса:
Первый вопрос. Я хотел использовать try - catch обработку исключений при вводе ставки, дабы пользователь не мог ввести текст, отрицательное число или ещё какое говно, но в таком случае переменная ставки становится локальной для этого {трайкэтч блока ебанного} и я не могу использовать её дальше.
Как ещё можно запретить пользователю вводить всякую хуйню которая не должна быть введена?
Я там чуть дальше проверил введено ли GO, но там текст который должен быть введён заранее известен, так что там это можно было перехватить вручную.
Второй вопрос.
Как теоретически можно было написать эту программу без goto?
Мне аноны выше уже пояснили и я в интернете посмотрел, что если goto используешь то ты лох ебанный. А по мне так охуенная команда, чем её заменить в данном случае вообще не ебу. Видимо я лох ебанный.
Сорян за тупизм если чё.
Какие забавные деды из замшелого прошлого к нам в тред залетают.
> Первый вопрос.
Иди нахуй.
> Второй вопрос.
Иди иди, не оглядывайся.
try - catch только для непредвиденных исключений.
Проверка ввода делается в if если ввёл хуйню пишем что ввёл хуйню и просим ввести еще раз.
Если у тебя конструкция if else превращается в if else else if то нужно использовать switch
ну и goto у тебя тут для возврата к началу игру, это делается через while
Ах да, ещё вопрос.
Почему мне не позволяют написать if (slot0 & slot1 == slot2)? Всё же логично: если А и Б равны В, то делается то то. В чём проблема?
Ошибочник говорит int в bool не удаётся ему преобразовать, схуяли ёпта? Чё он вообще имеет ввиду?
> если А и Б равны В
> if (slot0 & slot1 == slot2)
Удивительно, что у тебя с таким подходом вобще не всё красное.
& - это оператор побитового умножения
С учётом приоритета операций получается
if (slot0 & (slot1 == slot2))
slot0 - int
slot1 == slot2 - bool
Получается хуйня.
То, что тебе надо, это if (slot0 == slot2 && slot1 == slot2)
>Как ещё можно запретить пользователю вводить всякую хуйню которая не должна быть введена?
Можно использовать TryParse и сделать ставку uint
Можно читать посимвольно и не давать вводить ничего кроме циферок
Можно вынести в метод, и внутри метода try-catch, а результат уже возвращать из него
Вариантов много.
> Как теоретически можно было написать эту программу без goto?
Ну, я бы как на прикриплейд...
Но мне и твой вариант норм на самом деле.
Да, проверку что деняк на ставку не хватает - забыл.
Пасиба за пояснения.
>>110243
Пасиба за пояснения, я на удивление понял что ты написал. В учебнике по которому я эту парашу изучаю был приведён список приоритета операторов, но я подумал что автор в залупу лезет и это не особо важно. Мол, как в математике 4 класса, сначала всё что в скобках, потом умножение/деление, потом +-, мне этого хватит, чё там сложного, а хуй там.
Написал себе на листочек приоритеты и наклеил на стол чтобы всегда были перед глазами.
>>110246
Пасиба за пояснения. Проверку денег на ставку я и в своей проге забыл, так что всё норм.
![234234234.png](https://2ch.life/pr/thumb/3097760/17120849846440s.jpg)
Всё пофиксил по вашим советам, дружба с goto всё, теперь while мой лучший друг.
Прикольно. Малаца.
>Пасиба за пояснения, я на удивление понял что ты написал. В учебнике по которому я эту парашу изучаю был приведён список приоритета операторов, но я подумал что автор в залупу лезет и это не особо важно. Мол, как в математике 4 класса, сначала всё что в скобках, потом умножение/деление, потом +-, мне этого хватит, чё там сложного, а хуй там.
>Написал себе на листочек приоритеты и наклеил на стол чтобы всегда были перед глазами.
Вот это правильный подход. Люблю таких ребят которые не ноют в стиле "анон посоветуй гайдов как изучить язык", а с ноги влетают, начинают делать что-то сами и разбираются по ходу.
нормальные люди ставят скобки, а не выделываются.
Забыл его убрать (хотя и с ним работать будет)
На первый взгляд выглядит нормально, но когда попытаешься сделать сделать что-то более крутое, у тебя будет цикл, вложенный 10 раз.
По хорошему оно делается через state machine.
Ты че такой душный. Чел только учится, ему хотя бы понять как TryParse работает, а ты уже про стейт машину задвигаешь.
>Конкретно с дикшинари - он же просто удобнее в куче случаев.
У него KeyValuePair ридонли, что вечно ставит палки в колеса.
Нет никакой связи. Про словарь ты пишешь чушь. Это один из базовых элементов и используется немногим реже чеиюм лист
> new List<MyStruct>()
Чем ебаться со словарём. Это какой-то пережиток прошлого. Да, когда-то словари были крутой инновационной идеей
> сматрити, у меня есть ассоциативный массив, в котором вместо индексов свой тип данных!
> > охуеть! крута!
Но время их прошло.
![1712175568268.png](https://2ch.life/pr/thumb/3097760/17121755692160s.jpg)
Посоветуй хороший годный редактор ХМЛ файлов?
А я пока что посоветую пикрелейтед. Недавно нашёл и доволен.
Этот параметр ридонли, но кто имеет право его менять и как меняет? Я хочу себе подобное реализовать, чтобы пользователь имел доступ к Width, а если значение double.NaN, то родительский элемент меняет ActualWidth.
Или может быть дочерний элемент подписывается на события родителя и сам меняет ActualWidth? Непонятно. По идее ридонли нельзя менять снаружи или есть какие-то трюки?
![2024-04-0402-51-37.png](https://2ch.life/pr/thumb/3097760/17121889226330s.jpg)
Тут нет подсказок, никакой новой информации. Мне кажется, что стандартный редактор вижуал студии куда интереснее.
Как вообще с этим работать когда у тебя есть биндинги? Не показывает какой цвет указан и не дает его отредактировать в колорпикере. Не показывает какие вообще есть доступные свойства и значения у класса. Нет подсветки ключевых слов.
Я так понял ты его установил потому что сложно читать в обычном виде? На самом деле быстро привыкаешь. И не стоит обращать на форматирование в том же MDSN - оно уебанское и нечитаемое.
Знаю что есть дополнение, которое позволяет сортировать порядок свойств в xaml. К примеру, чтобы свойство Name всегда шло первым. Это позволяет не рыскать каждый раз глазами в поисках нужного свойства. Можно вроде настраивать какие свойства переводить на следующую строку.
Ты совсем тупой что ли?
Словарь - это когда тебе элемент надо находить за O(1), а не O(n).
Пишут блять свои листы, а потом запрос несколько минут обрабатывается вместо 500 мс.
А потом у таких как ты программы жрут ресурсы и работают медленно.
Когда ты вызываешь list.FirstOrDefault(x=> myStruct.Id == id), то программа тупо проходит по всему списку, пока условие не совпадет, хоть до конца списка. А если список огромный?
Словари индексируются и его использование это требование по оптимизации к конкретной задаче.
Это вообще из мира iqueryable
Бенчмарк спорный. Т.к. там по факту используется статика ничего относящегося к конкретной таске не создается. Компилятор может их как угодно наоптимизировать. Я бы еще внутрь какую-нибудь реальную работу запихнул.
ему там пояснили в первом коменте.
![нраица.png](https://2ch.life/pr/thumb/3097760/17122294965710s.jpg)
У меня пекарня дедушкина не тянет студию. Только вс-код, в котором нихуя нет. Только дополнение на автозакрытие тегов, которое помогает, но не сильно. Такшта вотета в древовидном виде выглядит вполне сносно, жаль что автодополнения нет, но названия элементов можно чекать по схеме, если она есть и если её подключить. (А её тоже нет, лолкек).
Алсо в этом редакторе любой хмл формат можно открывать. Например, я для прикола файл манифеста открыл и он мне показал ошибки, которые я исправил (один копипащеный тег был скопипащен без объявленного неймспейса).
Можно открывать файлы csproj и манипулировать группами настроек. Аппконфиг, юзерконфиг. Да любые хмл-лайк файлы, карочи.
И что самое главное - это оффлайн-приложение. С онлайн-редакторами на дедушкиной пекарне тоже не уедешь далеко.
>Если у тебя конструкция if else превращается в if else else if то нужно использовать switch
А нужно ли?
Чиво?
> ICommand ExitCommand = ReactiveCommand.Create( () => AppVM.ExitCommand.Execute(null) );
Но это же форменное безобразие так делать. Так мне не дадут.
Я уже пробовал передавать в конструкторе. Кнопка тупо выключена оказывается.
Зато надежно, ничего вдруг не сломается. Да и лично я не видел больше десятка вложенностей вью моделей
и в итоге по конструкторам ходит 100500 вот таких вот параметров.
и это еще если не используется вьюмодельлокатор какой нибудь
Карочи, послушав ваши ответы, я нихуя нипонил. Делать предлагается так:
модель - содержит метод Exit()
главная вьюмодель - содержит метод модели в который загружает инстанс модели и работает с ним, в том числе создает у себя команду, ExitCommand(model.Exit) для своего вью.
дочерняя вьюмодель - в конструкторе получает модель как обязательный параметр и работает с ней, в том числе создаёт у себя аналогичую команду.
То есть, мне не нужно вообще вьюмодели друг на друга ссылать. Достаточно ссылать им модель.
он к тому что ты должен таскать инстанс команды куда тебе надо и там присваивать команде во вьюмодели. Тогда вид будет видеть именно правильный инстанс и реагировать на него
так что НЕ создает аналогичную команду, а использует ту из конструктора.
другой путь - глобальный контекст, ты им не ходи.
> так что НЕ создает аналогичную команду, а использует ту из конструктора
Блять. Я с этого и начал. >>112913 >>112924
> Я уже пробовал передавать в конструкторе. Кнопка тупо выключена оказывается.
Я тут ещё загуглил. Может проще во вьюшке в хамле дополнительно датасорс указать другую вьюмодель для конкретного элемента?
> другой путь - глобальный контекст, ты им не ходи.
Это понятно. Глобальная вьюмодель выглядит удобной, но это же год обджект форменный.
Ну смотри. Обычно нет магии - если вьюха(и) видит один инстанс команды, то она за ним и следит.
Но что такое эта реактивная команда под капотом? я лично не знаю - я для авалонии использовал подход, что и для WPF. Я уважаю реактивный подход...но на андроиде или подобном, а в десктоп приложухах только мешает.
По идее авалония знает про реактивность и может кастовать ICommand до реактивной команды и подписываться на нее. А что если подписки 2 то как это? а хз. Может ты на это наткнулся, а может где то в другом у тебя проблема и вьюха видит не тот инстанс что ты думаешь. Влепи конвертер и увидишь
>>113182
Это не совсем про это. Типичные проблемы - нужно таскать обязательные параметры (вот эта команда тому пример), потом лайфтайм, потом мессенджер (ну да можно общий и токеном рулить, а вот мелкие сделали что ты указываешь ИНСТАНС мессенджера), потом диалогсервис (самая гадская штука кстати).
В итоге все это объединяешь в какой нибудь Context и вот у тебя как в андроиде - везде ходит Context. и все на тебя смотрят и ругают что у тебя вьюмодели прибиты гвоздями в иерархии (а ты смеешься с их потуг управлять временем жизни подписок и работы с диалогами)
но безумие не остановить.
И раз ты передаешь везде контекст, то... а ведь можно сделать общие вьюмодели для раздела....и вообще в них логику вытащить (это ж болезнь вьюмоделей).... и вообще разве нельзя на них прямо биндиться из вьюхи без всяких FindAncestor? да можно конечно...и вообще это не рутовые модели, а этакие....ммм...presenter-ы.
не не не, передавай в конструкторы
> передавай в конструкторы
Вот я сделял как сам написал выше. Этот пикрелейтед 1 - это тот контекст как ты пишешь?
Не вижу у тебя на скринах никакой передачи чего либо в конструкторы.
А мой контекст - у меня все вьюмодели принимают контекст в котором они существуют. (ну кроме простых вьюмоделей которым ничего из контекста не нужно)
Туда я прячу лайфтайм и это дает удобный запуск диалогового окна без мороки поиска родителя (что особенно жопа если у тебя вьюха)
> Не вижу у тебя на скринах никакой передачи чего либо в конструкторы.
А вот так? Теперь это контекст?
нет конечно. это просто ты передал нужное вьюмодели через параметр. Каждой вьюмодели что то нужно или не нужно.
мой контекст это просто набор доп обязательных параметров в рамках которых вьюмодель существует - у меня это лайфтаймы, связь с родительским окном, мессенджер, общие вьюмодели ака презентеры.
я не одобряю это, но в обычном подходе жить сильно сложнее
но тебе это не надо.
Какое уж тут развитие, это деградация. Тесты мне не нужны, а вот скорость рождения фич крайне важна.
но идея банальная же - заводишь класс Context, куда складируешь все нужно и таскаешь везде
каждая вьюмодель у меня так
public class MyVm(Context parent) : ViewModelBase(parent)
если рождаю вложенные то так
new ChildVm(Context())
а если нужно переопределить что то то переопределяю
new ChildVm(Context(childLifetime))
поэтому вм любой вложенности завязано на диалогсервис который знает к какому окну оно относится и можно открыть 2 окна и 2 мессаджбокса, то есть на каждом (в WPF так прямо нельзя...но если хочется, то можно, а в авалонии вроде всегда можно было)
туда же в контекст можешь впихнуть и AppModel/State и достать его в любом месте. Добавить где то на уровне что то еще, что будет видно только во вложенном.
В основе всего у меня лайфтаймы - я их обожаю. С них все началось. Ну и гемор с окнами добавил - вот я плюнул и теперь контекст везде
Такой же подход без контекста слишком геморный и в итоге "остался только один (подход)"
но это не по канонам вовсе, а "мне за тесты не платят, а за фичи платят, в жопу чистоту кода"
ну почти - если он не нужен, то он и и не нужен.
MVVM - это высер менеджеров из микрофофта, им надо было впарить новую версию вижуал студии, вот и навалили с подливой. По сути же это обычный MVC, где модель объединили с контроллером, а вью написали на уебанском xml. В ангуляре компоненты работают точно так же, но никто не называет это новым паттерном Component-Model-Typescript.
ничего подобного. это не MVC, потому что в MVC никто не держит в себе состояние визуальной части, а "рисует само себя" в итоге логику состояния вида нужно дублировать если кросс
Дай угадаю: ты учился по методичкам от микрософт?
Суть mvc очень простая: декларативно описывать интерфейс, чтобы можно было просто написать юнит тесты. Все. Если тебе при нажатии на чекбокс надо показать панель и ты хочешь протестить эту логику, ты вместо вызова panel.Show() возващаешь дтошку с полем IsPanelVisible и биндишь его на свойство Visible у контрола. В тестах ты пишешь Assert.True(vm.IsPanelVisible) и все. Ни о каком хранении состояния в паттерне mvc речи нет.
> в итоге логику состояния вида нужно дублировать
Двачую.
>>113262
Ну примерно понял. Я днём что-то похожее начал ваять, но ничего не заработало. А раз это деградация, то и ладно, оставим. Я прямо сейчас выработал для себя будущую архитектуру, как видно из скринов, будет общая модель всего приложения. Максимально совместимая с юнит-тестами и всё такое. Она ничего не знает о вью/вьюмоделях, она просто делает свою работу: поднимает данные с диска, считает их, кладёт новые данные по пропертям. И всё. Она знает о существовании приложения и имеет методы сохранения данных перед шатдауном приложения.
С другой стороны есть несколько вьюмоделей, которые знаюо о модели, получая её в конструкторе. Кроме стартовой вьюмодели самого приложения, она поскольку стартовая, то она и создаёт модель, и распихивает её по всем остальным. И тут возникает вопрос... Так, блять... Падажжи...
У меня получается два год-объекта, которые знают обо всех окнах, и при этом дублируются: модель и кодбихайнд приложения. И как тогда быть?
Вместо того, чтобы писать контроллеры в простом анемик стиле, как в микросервисах, ты нагородил архитектуру ради архитектуры и уже сам запутался.
также биндинги это своеобразные подписки на состояние
а значит всякие там реактивные штуки профита не несут.
это понятно что реактивное свойство оно как событие и на него можно подписаться, фильтровать и там того этого...и что? часто ли это нужно? нет. обычно INPC и "вид сам разберется" достаточно.
а раз так то свойства это просто свойства
если по клику на кнопку нужно что то запустить - ну простой хелпер ехекутор который в удобной манере что то запустит, поменяет IsBusy флажок, отдетачится от гуи потока, ну и помрет как положено если вьюмодель сдохла.
>>113282
Ты чет путаешь. Биндинги это про MVVM. И потому что именно нужно хранить состояние. Точно так же как и храним его в MVU(I)
в этом сама суть этих паттернов
и MVC так хреново подходит для десктопа, что там юзается MVP
>>113288
ну как деградация. Просто это не по канону для некоторых типа "как я могу эту вьюмодель передать куда то еще ведь она привязана к контексту, типа расшарить". На что можно спросить - "а зачем ее передавать, это как с оператором goto - хз где вы его используете"
Просто для тестирования же нужно этот контекст заполнить, типа он как "сервис локатор" (на самом деле нет)
Так что все это спорно очень.
То есть мввм фреймворки так не делают. Ну так они и лайфтаймы не делают как бы. У МВВМ фреймворков обычно weak путь, а у меня исключительно стронг - строг подписки, все стронг. Нет проблем с "а кто вызовет Dispose" - окно или воркспейс закрылся и все вьюмодели сдохли и сразу же прекратили работу. Без лайфтайма удачи тебе кенселить операции.
поясню на примере
ты открыл немодальное окно. там у тебя само собой рут модель и далее целый граф дочерних вьюмодей. В каком то уровне вложенности ты начинаешь операцию...и закрываешь окно. Как ты прервешь эту операцию? Как ты свяжешь CancellationToken с закрытием окна?
Каскадно пропишешь Dispose? Но в MVVM в WPF так не принято, потому что можно забыть вызвать поэтому обычно полагаются на weak во вьюмоделях.
Привяжешься к закрытию окна, создаешь CancellationToken - и этот токен протащишь по всем уровням как своеобразный лайфайтам - ну вот тебе лайфтайм ака контекст ( и ты пришел к тому же что и я)
> в простом анемик стиле, как в микросервисах
Любопытная инфа. Почитал. (Нихуя не понел, правда).
> ты нагородил архитектуру ради архитектуры и уже сам запутался
Никакой путаницы, щас просто надо подумать, где прописать хранение окон.
>>113294
> Без лайфтайма удачи тебе кенселить операции.
Лайфтаймы еще предстоит понять, а тут вон уже анемик подкинули выше.
>>113298
> В каком то уровне вложенности ты начинаешь операцию...и закрываешь окно. Как ты прервешь эту операцию? Как ты свяжешь CancellationToken с закрытием окна?
> немодальное окно
Нуууу, например: Все окна привязаны к БД (необязательно настоящая база данных, просто датасет, умеющий данные СоздаватьЧитатьОбновлятьУдалять), а значит, закрытое где-то окно послало в базу команду отмены. А БД эта, опять же лежит в модели, например как обсервабле коллекшон.
>Лайфтаймы еще предстоит понять
а понять их просто. тот же CancellationToken суть лайфтайм просто немного с другой семантикой. Типа "токен отмены". Но взгляни на него как на "токен отмены существования компонента" и таскай его по конструкторам и вот тебе лайфтайм. Каждый кто хочет завязаться на время жизни этого токена должен добавить себя к нему через Register и когда токен протухнет - все они помрут.
Настоящие лайфаймы просто сразу удобнее - знают про Dispose, позволяют правильно терминироваться (нужно в обратном порядке диспозить, а не абы каком), SequentialLifetime (вызови просто Next и старый умрет, новый родится) - из за чего родился класс и SequentialCancellationSource и удобно же блин, ну и прочий разный сахар с Try позволяющий не выполнять что то если лайфтайм уже умер, запускать таски не позволяя сдохнуть лайфтайму и так далее.
В разрезе вьюмоделей достаточно что вьюмодель живет в каком то лайфтайме (нет отличий от CancellationToken) и передает свой лайфтайм во все подписки и детям. Если лайфтайм того, то все подписки автоматически отпишутся и весь граф диспознется
>Нуууу, например: Все окна привязаны к БД
жуть какая то. но опять же - вьюмодель что заинтересована в этом знании должна как то об этом узнавать. А значит ты притащишь или датасет этот через все вьюмодели или обертку над этим датасетом....ба. а это тот же лайфтайм просто под капотом дико реализованный.
https://metanit.com/sharp/aspnet6/12.1.php пытаюсь по этой статье сделать
>У меня пекарня дедушкина не тянет студию.
Прими мои соболезнования. Но на самом деле это штука слабо лучше текстового редактора. Делать что-то сложное на нем я себе не представляю, особенно когда у тебя ресурсы в разных документах.
Все остальное в студии тоже есть.
Мне тоже интересен этот вопрос. Скоро коснется и меня.
Возможно нужно почитать доки, может есть какие-то стандарты.
Подозреваю, что есть шрифты, где толщина является частью названия. Это буквально их название, например ArialBlack.
А на C# что-то пишут кроме десктопа (в России)?
Кен экзекьют параша полная. Она выполняется один раз при загрузке и больше никогда. Я ее всегда возвращаю True, либо делаю метод, который принудительно дергает кен экзекют.
Еще была мерзотная ситуация, когда то ли фокус не пришел на кнопку толи еще что, но кнопка или меню тупо становились серыми даже с кен экзекьют = true. Каждый раз с этим борюсь и каждый раз забываю сделать себе пометку о причинах. Возможно что-то связанное с порядком загрузки.
Авторы ReactiveUI исправили это недоразумение (уж не сочтите за рекламу, можете пользоваться комюнити тулкитом, всё нормально, или даже своим велосипедом, никто не настаивает).
Они подают на вход своих команд Observable<bool> вместо bool и он внутри тулкита хитро подписывается где надо на обновления, и тебе ничего дёргать не нужно. Это я вычитал напрямую в их документации. И по первоначальным тестам всё действительно работает.
Правда у них там висит предупреждение, что работает это всё только в рамках одного потока, или контекста или ХЗ чего, и там сказано, что если вам надо вы можете дополнительно что-то там сделать.
>Warning For performance reasons, ReactiveCommand does not marshal your canExecute observable to the main scheduler. You almost certainly want your canExecute observable to be ticking on the main thread, so be sure to add a call to ObserveOn if necessary.
Очевидный вариант, это когда ты реализуешь интерфейс в наследнике, а не в базовом классе, но проблема в том, что 90% всех свойств находятся в базовом классе, а наследников дохрена.
Это что же, мне копипастить метод с клонирваонием всех свойств в кадом наследнике?
Если же я создаю реализую IClonable в базовом классе, то он возвратит мне экземпляр не того класса, который я ожидаю.
Тут должно быть что-то вреде дженерик Clone<T>() или Clone(BaseClass target).
>Кен экзекьют параша полная
смотря где. Если WPF, то выполняется при потере фокуса или ручном вызове "инвалидируй все команды"
В авалонии я сам писал этот CommandManager вроде. Конечно правильнее когда инвалидируются только зависимые команды, но это уже геморно и подходит только для реактивной модели.
В чём плюсы по сравнению с веб приложением? Сейчас если что то надо с интерфейсом я делаю asp net core приложение с мордой в вебе.
если ты пишешь под андроид и тебе хочется писать и под десктоп - то, возможно, да
иначе нафиг
Я бы сказал что гуй на нём редко пишут относительно сервисов просто с гуём больше проблем и вопросов.
А вообще всё что может джава то может и шарп и даже больше
> В авалонии я
Напоминаю, что реактивностью там занимается Reactive UI и говорить следует о нём. Так-то его можно подключить к любому проекту и юзать. Хоть в консольной утилите с консольным интерфейсом.
нет не так. вон обновил авалонию и отвалился Subscribe(Action)
тык мык - оказывается исчезла зависимость от пакета реактиве
так что Reactive UI это просто типа рекомендуемый дефолтный и (ну авалония его понимает), а не единственный. На авалонии можно писать с любым MVVM фреймворком, а не упарываться в любом к Reactive UI (и его особенности)
> На авалонии можно писать с любым MVVM фреймворком, а не упарываться в любом к Reactive UI (и его особенности)
Верно и обратное
> На Reactive UI можно писать с любым MVVM фреймворком, а не упарываться в любом к авалонии (и её особенности)
Я об этом и пишу.
Я вот позавчера смотрел длинный видос про авалонию с комюнити тулкитом. И там всё тоже красиво. И автор вежливо вначале сказал, что не осуждает пользователей Reactive UI и считает его годным, но сам он выбрал для себя комюнити тулкит и лабает на нём.
Если кому интересно, вот: https://www.youtube.com/watch?v=bCryIp9HqIM
![image.png](https://2ch.life/pr/thumb/3097760/17124063097790s.jpg)
Правильно ли я понимаю что Thread.Sleep блокирует поток и в случае если в этом потоке работает что то еще то это тоже остановится? А Task.Delay делает паузу только в текущей таске?
И стоит ли вобще делать паузы при ожидании чего то в while ?
await Task.Delay это просто эквивалент любоего другого асинхронного метода типа await DoSomethingAsync()
если в DoSomethingAsync() влепить таймер и TaskCompletionSource то это и будет Task.Delay
>при ожидании чего то в while ?
лучше не ожидать, ведь в этом и смысл тасков - "не жди, я сам позову когда будет готово"
в коде на скрине с await Task.Delay ты отпустишь поток и запланируешь продолжение в тредпуле
Если у тебя метод асихронный, то делай сразу Task.Delay
Зачем тебе Thread.Sleep? Если в твоей асихронной функции не будет await, то она будет работать как обычная синхронная с блокировкой потока пока она не завершится.
>И стоит ли вообще делать паузы при ожидании чего то в while ?
Если это Delay, то почему бы и нет? Только вайл у тебя должен быть в асинхронном методе, который ты ожидаешь.
К примеру у меня была асинхронная функция цветовой пипетки, которая брала цвет пикселя с экрана через определенный период времени. Внутри был цикл while c Delay, который работал до тех пор пока пользователь на нажимал ЛКМ.
А еще вайл используют при ожидании завершения таска. Так я, например, делал асинхронное диалоговое окно.
![image.png](https://2ch.life/pr/thumb/3097760/17124085900300s.jpg)
>>113901
Сложна все эти таски хуяски. Я когда пишу то как то по наитию делаю(
Вот например, таска в while появится значение, это может быть что угодно. Стоит ли туда добавить паузу что бы while не прыгал и не проверял в if? Ведь значение хз когда появится и можно было бы сделать Thread.Sleep(1000);
Будет ли профит в виде свободного процессорного времени?
Для примера, параметры приложения это модель или суб-вьюмодель основной модели? По своему объему похожа на отдельную вьюмодель, к которой обращается отдельное окно.
Но в то же время что мешает ей быть моделью? Все равно доступ к параметрам идеть через основную вьюмодель.
нет ничего сложного в тасках
таска просто объект который показывает статус какой то работы и позволяет дождаться (читай подписаться и запланировать продолжение) окончания таски
и ты снова делаешь фундаментальную ошибку - не нужно проверять "появилось ли значение". Нужно сделать какой то вариант уведомления типа AsyncManualResentEvent и тогда после установки значения дернуть его. работает как обычные не-асинк вейтхендлы - принцип одинаковый.
вьюмодель содержит состояние "нам нужно отобразить это". На INPC не смотри - это не исключительно видовое, о чем даже неймспейс интерфейса INPC говорит.
И да, ты не обязан создавать вьюмодель чтобы обернуть/перенести_данные с модели
Тут просто главное не забывать про мемори лики (знать подводные камни)
параметры приложения - модель.
Спасибо
Помогите кто-нибудь перевести код с Первой пикчи на новую версию ASP, где нет класса Startup, а есть только класс Program. Я пытался сделать с помощью метанита, но нихрена не работает, а у меня уже мозги кипят. Вот сам код:
string path = Environment.CurrentDirectory;
var _confstring = new ConfigurationBuilder().SetBasePath(path).AddJsonFile("DbSettings").Build();
builder.Services.AddDbContext<AppDBContent>(options => options.UseSqlServer(_confstring.GetConnectionString("DefaultConnection")));
Мне нужно подключится к файлу "DbSettings.json" и к строчке "DefaultConnection", который находится в самом пространстве имён проекта
На метаните подключаются к appsettings.json, а мне нужен другой файл
> Кен экзекьют параша полная. Она выполняется один раз при загрузке и больше никогда. Я ее всегда возвращаю True, либо делаю метод, который принудительно дергает кен экзекют.
Вообще-то все правильно. Как и у любого observable свойства ты должен сам вызывать обновление состояния команды, добавив метод NotifyCanExecuteChanged, который внутри будет вызывать событие CanExecuteChanged. А вариант с CommandManager в wpf это, простите меня, полная залупа, которая вызывает метод canexecute когда надо и не надо, забивая на производительность.
>Ведь значение хз когда появится
Ознакомься с токенами завершения. Есть возможность сделать событие когда таска завершится.
>Сложна все эти таски хуяски. Я когда пишу то как то по наитию делаю
Я в таких случаях пишу конкретную задачу. Пока непонятно для каких вообще целей тебе это нужно.
Есть куча вариантов. К примеру вот есть "именованные каналы", это такой мост передачи информации между несколькими приложениями или процессами. Там проблема в том, что первое приложение должно дождаться когда подключатся все остальные, а это неизвестно когда произойдет, может вообще никогда не произойдет. Вот тогда запускается асихронный метод ожидания, который в итоге создает событие, когда подключение удалось. Все что остается, это подписаться на это событие.
А есть еще токен завершения. Я его использовал в асинхронном диалоговом окне. В чем суть проблемы: пока окно не закрылось, не должен выполняться дальнейший код, но при этом я не должен был блокировать работу в первом окне. Что я делал? Я в асинхронном методе Show запускал окно и асинхронно ждал, когда окно установит статус что оно завершается, и только тогда мой метод Show завершался.
А чтобы я узнал что окно завершилось, я использовал токен, это такой экземпляр класса, который работает как Task.Delay, только у него есть свойство Cancel или Result, после установки которых ожидание прекращается.
Короче, описывай задачу и тебе подскажут решение.
Ну вот у меня довольно банальная задача — обновлять кен экзекьют каждый раз, когда вызывается контекстное меню. Вот как такое сделать?
Ситуация возникает чуть ли не в 96% случаев.
либо все команды регают себя в коммандмэнеджере ВПФ и он их всех заставляет инвалидироваться
либо же команды завязаны на изменения чего то от чего зависит их кен и тогда они всегда находятся в актуальном состоянии.
ты же пытаешься усидеть на двух стульях. Я сижу на полторах - у меня либо команда явно зависит от чего то, либо хрен с ней регается в коммандмэнеджере, но то ж ВПФ. тебе такое нельзя
>>113983
кроме десктопа на публику. Иначе же десктопа выше крыши.
> Ну вот у меня довольно банальная задача — обновлять кен экзекьют каждый раз, когда вызывается контекстное меню. Вот как такое сделать?
Даже не представляю зачем такая логика вообще нужна. Расскажи пожалуйста а я скажу, почему это говнокод
Ну и да, делается это через бехавиор. Подписываешься на событие Showed контекстного окна и устанавливаешь свойство IsContextFlyoutShowed в true, в сеттере также вызываешь метод MyCommand.NotifyCanExecuteChanged().
>Даже не представляю зачем такая логика вообще нужна. Расскажи пожалуйста а я скажу, почему это говнокод
Например в контекстном меню есть команда слияния несколько папок, но активна она при условии, что выделено больше одной папки.
> Например в контекстном меню есть команда слияния несколько папок, но активна она при условии, что выделено больше одной папки.
В таком случае ты должен обновлять CanExecute при изменении выделенных папок, а не тогда, когда вызываешь контекстное меню.
Зачем? Контекстное меню не всегда вызывается.
Хотя я понимаю о чем ты, эта кнопка может просто висеть в каком нибудь тулбаре. А привязка к поведению контекстного меню ограничивает возможности команды.
Просто иногда частота изменения состояния происходит в тысячи раз чаще, чем частота использования команды.
> Зачем? Контекстное меню не всегда вызывается.
Затем, что логика зависит именно от этого. Но если беспокоит производительность, то делай через бехавиоры как я писал выше или код бехайнд, бехавиоры же на рефлексии Но вообще в контекстном меню кнопка создается при каждом вызове и должна получать актуальное состояние CanExecute.
Затем что реактивный подход ПУШИТ изменение. Никто может не слушать но пушнуть ты обязан даже если это просто флаг выставить который команда ПОТОМ ПОТОМ прочитает
В большей степени проблема была как прописать путь до самого файла, но я сделал в итоге Directory.GetCurrentDirectory() внутри SetBasePath
private set;
> Каим образом обновляется ActualWidth, если он ридонли?
В геттере производятся вычисления и возвращаются тебе. Тебе кажется, что это переменная, и она как-то обновляется, а это не переменная и она вообще не обновляется. Просто каждый раз, когда ты к ней обращается, срабатывает геттер, производит вычисления и возвращает результат.
Шарпаны, а что вы в качестве якорей используете?
struct, class, record?
readonly, abstract?
Я, в принципе, понимаю, что так-то похуй, т.к. по сути из него нужно неймспейс достать и все, но вдруг есть какие-то общепринятые кодстайлы, а я не в курсе.
Допустим. А как тогда экземпляр знает какая у него актуальная ширина, находясь, например, третьим итемом в стек панели? Как он производит расчеты?
Понятно когда элемент находится в каком нибудь гриде, тогда он обращается к родителю и получает его актуальную ширину + марджин + паддинг. Но как быть с чем-то более сложным, где присутствует дополнительная организация чилдренов?
Ну например тебе нужно добавить в DI-контейнер кучу классов реализаций/наследников одного класса, создаешь класс пустышку (якорь) там где они все лежат и подкидываешь его в метод добавления, а он добавляет все нужные реализации из неймспейса этого якоря.
Ну или более каноническое в EFCore, добавление в modelBuilder конфигураций через
.ApplyConfigurationsFromAssembly(typeof(ConfigurationsAnchor).Assembly)
Ты знаешь какая там каша? Я потому и спросил, что может кто-то знает принцип.
>>115498
Короче, есть свойство RenderSize, которое доступно и на чтение и на запись. АctualWidth получает информацию из этого свойства.
Пытался поменять рендер сайз.
До изменений:
>TestBorder.Width: нечисло
>TestBorder.ActualWidth: 0
>TestBorder.RenderSize: 0;0
Вношу изменения
TestBorder.RenderSize = new Size(100, TestBorder.RenderSize.Height)
TestBorder.UpdateLayout();
Результаты:
>TestBorder.Width: нечисло
>TestBorder.ActualWidth: 100
>TestBorder.RenderSize: 100;0
Только визуально никаких изменений не произошло. Рамка не поменяла своих размеров.
никто к родителю не обращается
есть 2 прохода Measure и Arrange
measure проходит по всем детям и говорит им "вот я могу тебе дать такой размер, ты там посчитай желаемый размер который ты хочешь"
в Arrange же "вот тебе финальный размер -вписывайся и детей своих вписывай"
как то так
Спасибо, анон. Действительно.
Тоже подумывал сделать какой-то метод, в котором указывается допустимая область, а чилдрены сами рассчитывают марджин и свой размер.
Как сделать так, чтобы первый из обратившихся дернул инициализацию, а остальные если вдруг обратились в этот момент, то дождались когда инициализация завершится?
У меня решение такое:
1. Создать свойство IsInitialized
2. Создать nullable поле с TaskCompletionSource?
3. Создать асинхронный метод, который сперва проверяет IsInitialized и если false, то проверить наличие экземпляра TaskCompletionSource и авейтом дождаться завершения таски.
Какие подводные? Объектов не много, не больше сотни.
Без мемори барьера такое небезопасно делать. В конвейере процессора инструкции вызова конструктора и поднятие флага IsInitialized могут поменяться местами. Поток проверит что IsInitialized == true, и попытается обратиться к переменной, в которую еще не записана ссылка на "инициализированный" объект.
Вероятность словить такое в рантайме конечно же милипиздрическая, но детерменизм проебан. На ютубчике есть куча докладов на эту тему, даже на русском.
#if DEBUG
Console.WriteLine("Этот код выполняется только в режиме отладки.");
#endif
Это вопрос как выполнять определенную часть кода в Дебаге но не выполнять на релизе и что бы не дрочить проверками в релизе выполняется код или нет.
> Каим образом обновляется ActualWidth, если он ридонли?
>>115396
> срабатывает геттер, производит вычисления и возвращает результат
>>115477
> Допустим. А как тогда
>>115487
> Открой исходный код и посмотри сам.
>>115498
> Ты знаешь какая там каша?
>>115519
> Короче
> Пытался
> никаких изменений не произошло
Так вот как выглядит синдром Данинга-Крюгера!
И ничего страшного не случится ведь await обвешан барьерами
Слишком много гринтекста.
В фреймворка уже есть класс для решения этой проблемы
https://learn.microsoft.com/ru-ru/dotnet/api/system.lazy-1?view=net-8.0
Если прям нужна true-асинхронность, то возьми SemaphoreSlim и намути с помощью него и double check locking свой AsyncLazy.
Уже ответили но если это бизнесовая логика то не делай так. Остальные на говно изойдут и по делу
А почему не делать?
А как надо?
Вот например я в консоль вывожу логи. Или работа с файлами? Вообщем вся работа с тестовыми данными. Как правильно сделать?
Логи управляются через конфиг логгера, вырезав дебаг месседжи с мясом в проде ты себе же подлянку делаешь.
Тестирование делается банально мокнув нужный сервис, интерфейсы ёпта
Единственно где считаю уместным флаги компилятора это вырезать/заменять код дабы конечный юзер не увидел каких то секретиков. К примеру в дебаг сборке отключена проверка лицензий по коду и какие нибудь шифрования промежуточных данных
> человек, имеющий низкий уровень компетенции в какой-либо теме, начинает мнить себя знатоком этой темы
Где в перечисленном тобою гринтексте мнят себя знатоками?
То есть если в процессоре больше одного ядра, то вызов чего-то асинхронного может выполняться параллельно основному потоку. Правильно?
Нет. Асинхронный код может быть не готов к параллельному выполнению.
Асинхронный код не может в один такт пытаться делать две вещи, а параллельный может оттуда и ебля с синхронизацией/блокировками
Почитай как работает ивент луп в жс в качестве примера асинхронности или как фриртос распределяет кванты времени задачам
Асинхронность в первую очередь это когда у тебя есть какая-то операция, которая выполняется асинхронно относительно кода программы (сетевой запрос, запись на диск, ожидание какого-то события через аппаратный интерфейс и т.д.) и ты просто приостанавливаешь выполнение кода до того момента, пока внешняя асинхронная операция не завершится.
Ты можешь ждать завершения этой операции либо синхронно, в цикле, занимая поток ОС, либо, если ОС поддерживает работу с асинхронным IO, подписаться на событие завершения операции и освободить поток, чтобы не тратить лишние ресурсы. Как внешняя асинхронная операция завершится, ОС вызовет твой коллбэк и ты сможешь продолжить выполнение своего кода. В винде, к примеру, этот механизм называется I/O Completion ports.
Я заебался васянить:
stroki.Add("");
stroki.Add("");
stroki.Add("");
stroki.Add("");
stroki.Add("");
stroki.Add("");
stroki.Add("");
Для коллекций уже давно есть синтаксис инициализации.
https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/object-and-collection-initializers#collection-initializers
https://sharplab.io/#v2:EYLgtghglgdgNAFxAJwK4wD4AEBMAGAWAChcBGYrPAAi1IBYBuY4gNwmSoBsBnBKgXiowApgHcqAGSi8APLTwA+ABQBKYgG9iVbVQBEwKMAi64WnfoD2Rk2e37U14gF8mRYgDMLyYRADGACyU2Dl4OWC5eNSJNIh0aUgBOJVCVVycgA=
![image.png](https://2ch.life/pr/thumb/3097760/17125692206530s.jpg)
Если надо много и часто заполнять листы дефолтными значениями, то сделай себе Extension-метод/хэлпер и не страдай больше
![image.png](https://2ch.life/pr/thumb/3097760/17125701168770s.jpg)
Хотя вот так ещё лучше будет. Метод Span.Fill дико оптимизирован и активно юзает SIMD-инструкции.
а как List узнает сколько в нем элементов после прямого влезания в его хранилище?
Нужен чтобы не опрашивать какую-то программную сущность раз в n промежуток времени как долбаеб чтобы получить сообщение/новый стейт, а нормально тригерить у себя ивент только когда сообщение действительно придет.
Если ты спрашиваешь нахуя он нужен, то тебе он в проекте скорее всего не нужен. А если вкатун, то знать нужно.
мимокрокодил, никогда его не юзал, поправьте меня если написал хуйню
> и просто заюзал массив
А потом кстати, его можно легко переделать в список: .ToList();
Даже объявлять можно так:
> var stroki = ["","","","","","","",""].ToList();
>>116385
Бля ну для чего может быть нужен брокер сообщений? Чтобы делать event-driven architecture очевидно же! Чтобы микросервисы могли общаться. Я могу просто опубликовать событие - "товар куплен", а все кому надо, его получат. Это может быть склад, это может быть чат-бот, это может быть crm, это может быть email-оповещения, да что угодно. Тоже самое с ачиридями. Мне нужно обойти 500 сайтов например. Я могу создать очередь и обходить по 5 сайтов за раз в параллели. Ну и так далее.
> Я заебался васянить:
> stroki.Add("");
Так юзай for кста:
> List<string> stroki = [];
> for (int i = 0; i < 10; i++) stroki.Add("");
> Я заебался васянить:
Будь мужиком! Юзай Цикл While C ПостУсловием:
> List<string> stroki = [];
> do {
> stroki.Add("");
> } while (stroki.Count < 10);
Enumerable.Range(0, size).Select(_ => "").ToList()
> Что по твоему вообще диалог
Потомок класса окна.
У него есть статический метод ShowDialog(Window owner).
Меня учили, что вызывать этот метод должно окно-овнер, передавая туда экземпляр себя. Получается, если вместо окон у нас представления, то вызывать диалоги должны представления на уровне представлений?
ну у тебя был вопрос по MVVM
с MVVM все просто
модель - вообще логика приложения и она знать не знает про то что вообще где чего то отображается. она - все, что не относится к представлению
вьюмодели - отвечают на вопрос "что отображать". содержат визуальный стейт
вид - отвечает на вопрос "как рисовать"
при этом есть пара нюансов
- нижележащий слой не знает о вышележащем. модель не знает про представление в принципе, а вьюмодели про вид
- вид общается с моделью через вьюмодели, а не напрямую
- вьюмодели знают "что отображать". но знать не знают ни про какие особенности вида типа диалоговых окон
И тут возникает вопрос. А как же вон народ плодит всякие IDialogService?
А вот так - это так то нарушает MVVM. Просто вопрос такой встает и его нужно как то решать, то есть вносить какую то степень знания интерактивности на уровень вьюмодели. То есть все равно идет разрыв в логике вьюмодели, что ей где то нужно работать интерактивно. И тут кто на что согласен. Кто то выставит Func<> который обработает вид, кто то запилит медиатор и "эй кто то там выдайте результат", а остальные мудрят DialogSerivce, ведь инициировать что то на уровне вьюмоделей = обрабатывать это на уровне вида, а там всякий code-behind (а как там гласит - code-behind должен быть пуст). Ну да можно атачед пропертю или бехавиор...но тогда логика рвется. Ведь это может следить за каким то свойством и совсем не видно без 0.5 что присвоение этого поля оказывается что то там вызовет новое окно...да и где результат получать?
Так что абстракция диалога протекает и с этим ничего не поделать. Каждый выбирает свою степень протечки и удобства
Тут понятно. Будем думать.
> а как там гласит - code-behind должен быть пуст
А тут вообще непонятно, зачем до сих пор держат кодбихайнд, если хамл уже умеет буквально всё. Неймспейсы объявляет, биндинги биндит, стили перечисляет, взаимосвязи между элементами объявляет.
Просто вынести загрузку класса-представления в вызывающий компонент. Пусть условный
> xamlLoader(this) # из кодбихайнда
будет
> xamlLoader(ViewName) # из вызывающего компонента
И всё.
![4234234234.png](https://2ch.life/pr/thumb/3097760/17126885898550s.jpg)
Двощеры, нужна ваша помощь.
Задача такая: создать массив из 56 элементов, который представляет собой по сути колоду игральных карт. А это значит что каждой карты должно быть по 4 штуки. Тоесть первые 4 элемента массива, с 0 по 3, должны иметь значение 2.
Я написал код, который должен вроде работать, но он не работает и я слишком тупой чтобы понять почему. Он забивает в массив только первые 14 элементов, а не все 56. Помогите нахуй, у меня мозги плавятся.
ты не записываешь увеличенный i во внутреннем цикле
должно быть так:
deck[i++] = 0;
deck[i++] = 1;
deck[i++] = 2;
deck[i++] = 3;
вместо while, хотя не уверен что ты именно эти значения хочешь записать, твоя ass болтается в воздухе
>deck[i++] = 0;
>deck[i++] = 1;
>deck[i++] = 2;
>deck[i++] = 3;
даже не так:
deck[i++] = 0;
deck[i++] = 1;
deck[i++] = 2;
deck = 3;
последнюю не нужно увеличивать
Можно в одном цикле просто отбором целой части и остатка от деления индекса на 4
Чувствую себя вернувшимся в 2021-й год. Когда уже вышел .Net6, но ты вынужден был сидеть на Core3.1 (а местами еще и на Core2.1) и облизываться на новые фичи.
Сейчас то же самое. Уже вышел 8-й, на подходе 9-й, с кучей новых вкусных плюшек и оптимизаций, но ты вынужден будешь использовать 6-й еще года два.
Ну, а потом - отсортировать как надо, если надо, если не надо - не сортировать.
Чел, я бы с радостью хотя бы на 8 перешел. Но то говно (вроде Альта или Астры), на которое приходится сейчас импортозамещаться максимум 7 поддерживает и то так себе. А те лицензии которые они корпоратам продают только 6-ю версию гарантируют. И когда они доползут до нормальной поддержки новых версий - хуй его знает.
С версиями софта, там вообще боль. Тот же постгрес только 11-й версии в Астре (при том, что его поддержка закончилась осенью) и летом обещают 12-ю (которая тоже протухнет в ближайшую осень).
Делаю запрос через HttpClient:
var response = await _client.GetAsync("api/huinya");
Лезу через дебагер к reponse->RequestMessage->RequestUri->AbsoluteUri
копирую урл в постман, через постман все заебись - я попадаю в контроллер, через HttpClient в блейзоре - хуй.
Это при том что я пишу третий круд по бойлерплейту - код идентичен, уже раз 10 все перепроверил.
Все мои годы разработки сейчас тупо остановились на этой неведомой хуйне.
1. В браузере copy as curl и выполни
2. Загони под митм (чарлис, фиддлер, етц...)
3. Проверь что с методами
4. Смотри логи сервера
1. Все заебись, браузер/постман заходят в контроллер.
2. Проблема на стороне клиента 100%, это все на локалхосте.
3. С какими методами?
4. В логах ничего, и ничего в принципе и не должно быть если оно не находит контроллер - возвращает хтмл блейзор страницу.
Версия .net 7. Под третьим крудом я имел ввиду 3 таблицу.
Убрал с Program.cs на сервере кеширование/сжатие, авторизацию/аутентификацию и рейт лимитер, пока нихуя не дало.
Включен, но его отключение ничего не дало.
Очевидно есть зависимость от неких заголовков запроса. Попробуй в браузере сделать запрос аналогичный постмановскому
2. Ты пробовал или просто гнешь линию?
4. Поставь трейс на всё и там будет подробно расписано кто и куда идёт и как матчит
>>117949
>>117956
>>117972
Все отбой, я отправил запрос на апи когда он был еще не доделан, мне отправилась блейзор страница. Когда я написал апи она видимо каким-то образом доставалась из локального кэша, даже спустя несколько часов и ребилды. Нашел уже после того как начал менять имя апи на любое другое и оно работало.
Надо будет еще покурить как оно работает.
Вопрос: есть файл Json для базы данных, со строками:
ConnectionStrings": {
"DefaultConnection": "Server=(localdb)\\\\MSSQLLocalDB;Database=??????;Trusted_Connection=True;MultipleActiveResultSets=true"
}
Что поставить вместо вопросов после Database = ?
Код с инициализацией базы данных находится в DBObjects.cs. Если я прописываю её в вместо вопросов в json, у меня выдаёт ошибку как на пике 2
Название экземпляра бдшки. Зайди в субд через SSMS и посмотри как называется бдшка в которой хранятся твои сущности.
>Сап двач, изучаю ASP NET по этим видео:
Блин, чел. Не делай так. Хрен с ним, что это Гоша Дударь, но курс 4-х летней давности и по Core2.2
В реалиях .Net - он устарел еще года 2 назад, а сейчас его можно засохшим говном мамонта считать.
Заюзай хотя бы Метанит, там хотя бы информация достаточно свежая.
Microsoft.Playwright.PlaywrightException: "Browser does not support socks5 proxy authentication"
Прокся точно рабочая, так как я перед этим делаю гет запрос с ней.
> Как у вас голова работает так?
Свою первую переменную я объявил в 14 лет. В далёком 1997 году.
Я чет думаю, что что-то не так с моей кодой.
Вот.
https://pastebin.com/PYnXwZGf
![image.png](https://2ch.life/pr/thumb/3097760/17127721015810s.jpg)
Ну в документации же написано что можно
https://playwright.dev/dotnet/docs/network#http-proxy
Делаю как на скрине и всё равно нихуя
Ох уж эти ньюфажины.
Это не значит что браузер это умеет
Хотя не уметь сокс5 это гм в наше время
С другой стороны разве в браузерах указываешь тип сокса?
Может и тут так
>You can configure pages to load over the HTTP(S) proxy or SOCKSv5. Proxy can be either set globally for the entire browser, or for each browser context individually.
Да я по всякому пробовал, нихуя не работает
Значит тебе только на завод
Загугли лучше какие-нибудь уроки по EF. Желательно посвежее. Там будет все тоже самое, как работать с бд, но понятнее.
Вообще, лучший совет для вкатунов это все гуглить. Загули то, загули се. Сделай себе акканут с гпт 3.5. Загугли как. И задавай сетке любые, самые тупые вопросы. Вот кто тебе с удовольствием все разжует. Только не бери на веру прямо вообще все, что он тебе говорит. Этот лоботомит любит бессовестно напиздеть...
Ты понимаешь что дока для либы которая поддерживает несколько браузеров, а не для хрома который может что не уметь?
Потому что хром точно не поддерживает аутентификацию у проксей. Об этом к слову тоже написано в ошибке
Да уже не похрюкаешь, после февраля 22 рынок накрылся пиздой... За кабана держишься как за спасательный круг. Вокруг осталась одна Ява и голанг или православная жопа одина.
Тоже так думаю но по факту немного иначе.
Критерии поиска: от 200к, удаленно, без вышки, галочка зп указана выкл
Но есть одно НО, больно много проектов на шарпах это старое унылое говно времен 2016 года. А на го много новых проектов делается и вакух 300+ на го больше чем на шарпах.
Последний собес был в контору где было 2 тимы и внимание, в двух этих тимах было по 1 человеку и называли они себя лидами
Это сильно поможет для ASP NET?
Сейчас бы искать по тегу C# вакансии на .Net. Во многих его даже не указывают как требование.
Че эт за фигня, когда коммент к ПРу больше самого ПРа?
Чет у нас обычно:
Имплементировал фичу из беклога. Фича #123456
И в ПРе 10000 аддининов, 2500 удаления
Кто делает неправильно?
а еще указал специализацию программист, без нее результаты 800+ и разброс 10+- вакух
Сравнил опенсорс с энтерпрайзом, лол.
>Че эт за фигня, когда коммент к ПРу больше самого ПРа?
Побочка попенсорца. Там часто бывает, что обсуждение ПР может вылезти в большую дискуссию с кучей правок по ходу и откатами. Поэтому лучше когда вся информация собрана тут же и она максимально подробная, чтобы было меньше тупых вопросов и всегда можно было процитировать нужное. Плюс часто сылки на ПР используются в других статьях, поэтому тут их полнота тоже играет на руку.
В энтерпрайзе же ПР - это часто просто констатация факта: "Пацаны, я таску закончил, апрувните пулреквест кому не впадлу" там нахуй никому не уперлось не то что ревьюить твой код, но и даже описание к реквесту читать.
>Чет у нас обычно:
>Имплементировал фичу из беклога. Фича #123456
>И в ПРе 10000 аддининов, 2500 удаления
Если у вас внутренний проект с нормально настроенной интеграцией и по тегу Фича ###### автоматом формируется ссылка на нужную таску или страницу где-нибудь в конфлюенсе или редмайне, то вполне норм.
Есть только пара ньюансов.
1) Краткое summary на одну строку в коменте к ПР/коммиту и т.д. лучше все-таки писать. Просто чтобы когда ты список/дерево коммитов открываешь, сразу было видно что и когда было сделано, чтобы каждый раз не лазить по ссылкам выясняя что за херня тут твориться.
2) В голову начальства иногда приходит мысль "а давайте мы наш трекер задач заменим на другой он дешевле/лучше и т.д.". И вот на таких переходах имеют свойство проебываться все данные по таскам и прочая информация.
Я поэтому всегда пишу в заголовке коммита имя таски, и краткое summary на английском, потом в сообщении уже более подробно излагаю на русском, что там было сделано. При таком подходе в большинстве случаев для работы достаточно самого репозитория и в трекер приходится лезть, только за подробностями.
![людмурик серьезная.mp4](https://2ch.life/pr/thumb/3097760/17129118258640s.jpg)
308x320, 0:02
Я уже много лет пишу на C#, но не участвовал в high load проектах.
Можете подсказать хорошую литературу, кАналы на ютубе, где можно об этом посмотреть. Спасибо.
>1. IState
- корневой интерфейс, от которого происходит всё остальное. Содержит методы: Enter(), Exit(), Update(), IState Transit(IState next)
>2. IState<T> : IState
- типизированный интерфейс-потомок, содержит типизированные-параметризированные версии методов: Enter(T parameter), Exit(T parameter), Update(T parameter), не содержит транзита.
>3. State : IState
- реализация п.1. в конструктор передаются три Action и назначаются трём соответствующим зануляемым ридонли приват полям. Остальные методы при вызове инвокают, например: void Update() => _update?.Invoke() по такому же принципу Enter и Exit. Метод Transit реализован так, что вызывает Exit у себя, Enter у next и возвращает next. Нулль на next не допускается.
>4. State<T>: IState<T>
- И вот мы подходим к сути вопроса. В этом классе у меня выходят задвоения, от двух родительских интерфейсов приходят требования реализовать по два вида методов Enter(), Exit(), Update() с параметром и без параметра. Я хочу чтобы интерфейс как-то это дело автоматически обернул мне. Такое возможно? Я с самого утра гуглил, ничего толкового не нашёл. Пока что я рассматриваю параметризированные варианты методов как основные и в пустые методы прописываю перенаправление, с заранее сохранённым значением параметра, делаю, например для Update() => Update(storedParameter); Но это решение мне не нравится, ибо смахивает на костыль-код.
Я хочу, чтобы у меня стейт-машина по таймеру делала что-то навроде
> if (CurrentState is IState<float> FloatTyped) FloatTyped.Update(delta); else CurrentState.Update(); # где delta - это float
автоматом вызывая параметризированный апдейт, если текущее состояние типизировано.
Zalupka.Program.Main(String[] args) in C:\Users\MY_NAME_NAXOI\source\repos\Zalupka\P.......
Само приложение запущено на vps
Потому что инфа о строках на этапе компиляции вставляется. В конечном билде нет никаких строк, только байт-код с пометками что когда то это было строкой Х в файле У
> C:\Users\MY_NAME_NAXOI\
Поэтому все олдовые двачеры, уже один раз обожглись, и теперь все мы - C:\Users\User
Теперь и ты станешь одним из нас. При следующей переустановке шиндовс.
> А какая инфа еще пишется о моём пк?
Пишется на какие сайты ты заходил. И на какой секунде останавливал воспроизведение видео.
А как тогда компилить свои проги то?
Я не хочу что бы когда фбр вскрывала мой софт там были мои следы.
Да.
Убери реализацию интерфейса из одного из классов (базового или наследуемого), и наследуй интерфейсы один от другого (если необходимо)
![image.png](https://2ch.life/pr/thumb/3097760/17129436133440s.jpg)
Обычный типа универсальный подход это типа прикриплейд.
Суть в том, что стейт взаимодействует с контекстом, мутирует его и все это вот делает. Машина, просто содержит контекст и дергает какой-то метод Tick, Update, etc, все что тебе надо - ты в стейтах реализуешь и помещаешь в контекст от задачи.
А шо подробнее?
Вся информация необходимая для решения о переходе - хранится в контексте.
Стейт - сам принимает решение при апдейте что надо перейти в такое-то состояние в методе Update. Когда надо - изменяет внутренние состояние контекста.
Стейтмашина - просто периодически, по какой-то твоей логике - просто дергает у контекста Tick, Update и т.д.
Если хочется совсем универсальное - ты делаешь просто билдеры стейтов и контекстов, если, допустим, тебе в рантайме надо создавать стейтмашины.
https://github.com/dotnet/sdk/issues/16975
<PropertyGroup Condition="'$(Configuration)'=='Release'">
<DebugSymbols>False</DebugSymbols>
<DebugType>None</DebugType>
</PropertyGroup>
В файл проекта.
![bomzh.jpg](https://2ch.life/pr/thumb/3097760/17129951532170s.jpg)
https://habr.com/ru/companies/dododev/articles/573470/comments/#comment_23393296
Им говорят - вот на Java написаны Hadoop, Kafka, Elastic Search, а на вашем .NET что?
Они - "пук, среньк, ну это, можно подключаться к кафке из шарпа".
>вот на Java написаны,
На C/C++ целые операционки написаны. Покажи хоть одну написанную на Java.
Ну вот, например: https://ru.wikipedia.org/wiki/JNode
Только Java не предназначена для системного программирования.
А вот говношарп претендует на использование в энтерпрайзе вместо жабы (или сейчас уже нет)?
Всё, кажись понел. Вместо создания двух видов стейта, я создаю один вид контекста, имеющий несколько реализаций, и если мне нужно прокидывать дельту-тайм в апдейт, я делаю контекст для этого. И получаю два уровня: Сначала контекст-машина, с несколькими контекстами, которые уже являются стейт-машинами с несколькими стейтами.
Ммм... Гениально!
Так в том и прикол, что ниче на шарпе не написано. Все проекты - это мистификация.
Мы просто ходим на работу, получаем деньги, и литерли нихуя не делаем. Может быть раз в год самого смелого пошлют на какую-нибудь конференцию, чтобы он зубы заговаривал. А так - сиди-перди, получай бабосики и радуйся.
Оооо. Поборник фатального недостатка в треде
> Им говорят - вот на Java написаны Hadoop, Kafka, Elastic Search, а на вашем .NET что?
Paint.NET, если без гугла. Если с гуглом, то https://en.wikipedia.org/wiki/List_of_C_Sharp_software
Непонятно, что там за пердуны пукнутые на этом вашем хабре сидят? Сдаёца мне, это жависты под шарпанов косят.
Не будь как жавадебилы
Синдромом фатального недостатка болеют не все
Например гитлаб на руби, но почему то жавожабы вполне юзают его, а не орут "а чего он не на жаве"
Да я вроде и не бываю.
Неважно, на чём написан софт, главное, чтобы он делал заявленную задачу и делал хорошо.
А тебе точно нужен ссл на кестреле? Никогда не видел что бы в релизе кестрел стоял не за каким либо балансером с ссл терминейшеном
>Нормально ли скипать темы которые с трудом понимаешь или биться до талого?
Ни то ни другое. В таком случае нормально возвращаться назад прорабатывать базу и набирать опыт.
Если я записываю экземпляр логгера в статическую переменную:
>private static ILogger _log = Log.Logger.ForContext<MyBaseClass>();
То в принципе все методы могут иметь доступ к этой переменной. Но тогда начинается проблема с логгированием в наследниках класса.
Допустим в базовом классе есть метод ToString(), который пишет в лог:
>if (_log.IsDebug()) { _log.Debug("ToString: {0}", result); }
Допустим я создаю наследника базового класса, и скрываю переменную лога при помощи new
>private new static ILogger _log = Log.Logger.ForContext<MyInheritClass>();
Тогда я запускаю метод ToString() из наследника, но лог записывается применительно к базовому классу MyBaseClass, а не MyInheritClass. Проблема усугубляется, когда куча наследников юзает один и тот же метод, тогда хрен поймешь кто это сделал и когда.
Если же переменная с логом будет не статической, то я могу использовать virtual для переопределения, не понимаю как в статический класс передавать в экземпляр логера. Через параметры? Это же тупо. Нигде я не видел запрос логгера через параметры. Хоть вообще отказывайся от статических методов.
В любом приложении указан минимальный размер окна.
И если ты, к примеру при помощи SetWindowRect попытаешься указать размер меньший, чем минимальный, то окно уменьшится до минимального.
Конечно можно наговнокодить, например попытаться сжать окно до 1х1 пикселя, а потом замерить фактический размер, но это хрень — это вызывает лишнюю перерисовку окна.
> DI > static
Разве это делается для методов? Это делается для инициализации класса.
>Logging context
Не понял. У меня же и так
>Log.Logger.ForContext<MyBaseClass>()
Зачем тебе вообще статик? Все статики которые обычно юзаются можно подогнать под XxxUtils и экстеншены, то есть логирование там не нужно.
И под контекстом я имел ввиду скоупы которые дополняют контекст для уточнения что и где происходит.
>Зачем тебе вообще статик?
Метод вообще не использует данные экземпляра. Да, это по сути утилита или экстеншн, но ей пользуется экземпляр и там есть полезная информация.
>то есть логирование там не нужно
Почему? Есть какие-то правила логгирования?
Предположим у меня задача при помощи API изменить размер окна стороннего приложения. Метод по сути своей статический, но как мне узнать не спамят ли его и какой размер окна требуется?
Может показаться, что это надо сообщать до использования метода, но некоторые методы бывают многоуровневыми, содержащими в себе другие методы, например поиск дескриптора окна, анализ заголовка окна и прочее. И везде есть полезна информация.
>И под контекстом я имел ввиду скоупы которые дополняют контекст для уточнения что и где происходит.
А можно подробнее?
Суммарно все звучит как XY-problem. Есть подозрение, что тебе надо максимально уйти от статики.
Самое очевидное и простое не юзай статики, регай класс в di и инжекти в него всё что тебе нужно в т.ч. и логгер.
Из-за того что у тебя хитровыебанные статик методы код который их юзает толком даже не обложить тестами, только кучу всего и разом тестить.
Моё представление что статики должны быть максимально простыми что бы там банально нечему было ломаться
Так и гугли dotnet logger context scope. Без структурного логирования имеет мало пользы
> стилизовать все контролы под 11 винду
Но зачем?
90% кодеров всё равно будут свои стили накатывать.
Ну если тебе нужно чтобы в наследнике тустринг писал иначе - то тебе ОЧЕВИДНО нужно этот метод переопределять независимо от причин "иначе". И логгер вообще не причем.
>>126612
опять все сломают. они это могут. в итоге простое "переопределить цвет выделения" что раньше легко решалось добавлением цвета в ресурсы с нужным кеем - теперь решается полным переопределением шаблона на 10000000500000 строк
Как раз 90% будут. Умник, блять, выискался тут.
![image.png](https://2ch.life/pr/thumb/3097760/17134656574810s.jpg)
Шарпаны, а что вы будете делать если вам кабан LINQ запретит использовать?
Абы да кабы
Вспомню, что в шарпе есть синтаксис циклов.
Заюзаю F#.
Пердёж затроллил пориджей.
В общем. Позвал чел помочь с кодом.
Код - мой.
2 года назад писал. Я в душе не помню как он работает.
Это был код фронтенда.
Я просто в ужасе.
При этом - коде бекенда - я помню как работает досконально, хотя писал его тоже 2 года назад. Но там - я сразу такой: этот файл, такой-то метод.
Че за срань? Как блин так может быть? Почему я фронтенд пишу на отъебись, а бек - будто преподу буду защищать помню?
Я джсий тоже на пофиг пишу. Не ну а чо, язык сам располагает к этому, не моя вина.
![15937867776240.png](https://2ch.life/pr/thumb/3097760/17136048414550s.jpg)
Ты закрытый человек — любишь делать вещи, пока никто не видит.
Будем честны, для фронтенда нужно больше навыков, знаний и смекалки. Фронтенд это как социоблядь - мы их презираем, но повторить успех не можем. Проще сказать что нам просто не хочется.
А я с этим спорить-то не буду на самом деле.
Другое дело, что как фуллстек - я как-то всегда считал, что у меня +- одинаковые навыки и там и там.
А вот как-то так получилось вчера. Спросили по старому коду, который передали другой команде на поддержку. Я смотрю как баран, не понимаю - как я это и зачем писал, и что оно вообще делать должно. 1,5 часа просидел с челом, пытаясь вспомнить свой полет фантазии в тот момент, когда я это высрал.
Проект просто новый намечается. Кроссплатформенный. Десктопно-мобильный. И надо выбрать на чем UI делать. По результатам исследований три стула: Авалония, Eto.Forms, и как раз электрон.
Почему хочется электрон? Потому что таки в штате есть фронтендеры, которые нормально JS/TS, плюс есть база компонентов для веба, которые можно было бы просто заюзать и радоваться. Но вот про связку с .NET (я так понимаю, что типа надо чтобы .NET приложение было хостом и стартовало всю эту электронофигню) - я не пробовал и опыта не имеется.
С другой стороны - авалония. Выглядит почти как WPF, текущие бекендеры на нем начинали, и опыт как-бы имеется, но тогда всю хуйню визуальную опять придется с нуля хуярить, плюс - фронтендеров если подтягивать - им придется обучаться.
Eto.Forms - из-за этого треда боюсь даже предлагать.
Какой ещё успех
Фронтенд это жс
А это как жрать говно
Все эти фреймворки это просто "говно подано в красивой сервировке"
Но это всё равно жрать говно
Поэтому это стул не с плоской поверхностью
Avalonia + webview
> Почему я фронтенд пишу на отъебись, а бек - будто преподу буду защищать помню?
А теперь внимание, правильный ответ: Потому что фронт временен и меняется по велению моды и левой пятки маркетинговых менеджеров. Нет смысла посвящать ему много времени. Быстро загуглил, как биндятся события кнопок к командам вьюмодели, накидал и забыл. А вот бек - пишется на века. Меняется очень редко. Имеет повышенные требования к отказоустойчивости. Над беком приходиться долго думать.
![image.png](https://2ch.life/pr/thumb/3097760/17136272258100s.jpg)
Ткни пальцем где. А то я поиск по странице сделал и слова Linux не увидел.
> По результатам исследований три стула:
> Eto.Forms
На связи бывший форсер ето.формсов! Вставший на путь истинный, авалониевый. Там мобильный бэкэнд в зачаточном состоянии. А ты
> Кроссплатформенный. Десктопно-мобильный.
Таким образом, увы. Сам проект был бы хорош, но сообщество вокруг него собралось мизерное. Сам автор в одиночку не вытягивает одновременно баги фиксить и фичи допиливать. Проект буксует на уровне прошлого поколения интерфейсов.
Так что ето.стул смело вычёркивай.
Вот что выбрать то? ВПФ или Мауи? Я так понимаю авалония это библиотека для впф?
Склоняюсь к Мауи так как еще и на андройд хотелось б попробовать пописать.
Учи винформы.
Реактивный пакет ставь в проект и большинство современных UI станут реактивными.
Самые известные это
1. ReactiveUI https://www.nuget.org/packages/ReactiveUI
2. Community Toolkit https://www.nuget.org/packages/CommunityToolkit.Mvvm
wasm
Очевидно, где меньше замла...
Ой... Кажется действительно нету... >_<
Реактивный интерфейс - это свойство элемента управления вызывать изменения связанных данных или элементов управления из-за динамического связывания или дата-биндинга этого элемента.
Реактивность - это то же самое, что асинхронность. Если тебе кто-то говорит, что это не так, шли нахуй этого петуха.
А где в community toolkits реактивность? Почитал описание хелперов, про реактивность ни слова.
Петуха ответ.
Ценятся не слова, а дела.
Это пуш модель. Буквально все выставляет точку (ака поток событий) на которую можно подписаться фильтровать и комбинировать с другими потоками событий.
Как LINQ, но линк начинает работать когда кто то хочет получить результат (pull), а тут все начинает работать по событию (push)
В полной упоротости у тебя весь код представляет собой связанные цепочки с минимумом императивного кода.
бамп вопросу
авалония прикольная канешн, но она чёт по сравнению с впф раз в 10 больше озу кушает
Просто такой подход к кодированию. Более похож на фп
А что хорошего, что в впф есть CommandManager который обновляет все команды, а не только те, что нужно, при смене фокуса?
А тут обновляются только те, что зависят от источника.
Я не знаю как в реактиве в шарпе. Не вижу смысла юзать реактиве в десктопе (не заходит мне), не вижу в асп.нете.
Но я балуюсь котлином под андроидом. И вот там как раз предпочитаю эту модуль "все есть flow", а не императивную модель.
Потому что есть богатый набор функций для подписок, комбинирования, фильтрации и так далее. И все это автоматически подписывается и отписывается реагируя на lifecycle приложения. Я просто прописываю "вот это зависит от этого и когда источник изменится, то и это изменится".
Хотя писать в чисто таком стиле сложно. Читать просто, а вот писать....большинство скатывается в "подписался и вызвал метод в котором выставил свойства вьюмодели". А должен был выставить flow, и все зависимые свойства подписываются на этот источник и обновляются.
Даже банальное db.getUsers() возвращает не список юзеров, а Flow<List<User>>, хотя по факту он выплюнет по готовности список юзеров и все - тогда другие смогут подписаться на этот flow (впрочем то ж котлин - там богатейший набор "хочешь так, а хочешь этак" и обычный db.getUsers() превращается во флоу как 2 пальца)
У тебя в итоге вся система в этих цепочках и где то что то выплюнуло событие (хоть мышеклик)...и полетело это по всем зависимым цепочкам. В силу LINQ подобного синтаксиса описание кода прямо декларативное получается.
Те же биндинги в впф имеют такой же подход когда от источника к контролу. Ты просто прописываешь биндинги что от чего зависит (неудобно конечно ибо синтаксис ограничен) и дальше оно просто работает. ты даже не заботишься об отписке биндинга если контрол выпал из вида.
Ну и такое по всей системе
Если ты делаешь десктопное приложение для венды, то конечно, нет смысла запариваться со всякими там авалониями. Но анон выше заявил, что хочет сделать кроссплатформу.
Авалония предлагает кроссплатформу искаропки. Все основные десктопы, все основные мобилы и браузерный васм. С единой кодовой базой.
Так что смотрите сами, ребята.
> связанные цепочки с минимумом императивного кода
А что такое императивный код?
> выставляет точку (ака поток событий)
Что такое "выставить точку"?
Вопросы не праздные и не троллинг. Это скорее майевтика.
Императивный код выполняется построчно как описан
a=1
b=2
c=a+b
В linq ты описываешь декларативно. Ты же не пишешь вручную циклы и условия. Реактиве тот же linq только push
Точка/источник это просто событие в виде iobservable к которому можно прицепиться и писать в linq стиле (в отличие от обычных событий)
Пример винформс без биндинг и впф с биндинг
В виныормс по какому то событию (например сервер ответил и отдал данные) ты пишешь императивный код в котором меняешь состояние нужных контролах
С биндингами (по факту реактивня модель) все контролы будут следить за данными и обновят себя. Тут декларативный подхлд и в идеале только хамл и хватит
> Императивный код выполняется построчно как описан
> В linq ты описываешь декларативно.
Интересно заюлил. Это упоминание маевтики тебя так напрягло? В таком случае следующий вопрос. Почему "построчечность" это императивность, а "поточечность" это декларативность?
Иначе говоря, почему
> делай_раз
> делай_два
> foreach(a in b) делай_три
- это императивность, а
> делай_раз
> .делай_два
> .foreach( a => делай_три)
- это у нас волшебным образом превращается в декларативность?
потому что так оно и есть
"Императи́вное программи́рование — парадигма программирования, для которой характерно следующее: в исходном коде программы записываются инструкции; инструкции должны выполняться последовательно; данные, получаемые при выполнении предыдущих инструкций, могут читаться из памяти последующими инструкциями"
то есть описание инструкций по факту и есть выполнение этих самых инструкций при их же описании
а поточечность описывает выполнение декларативно и само выполнение может быть потом и неизвестно каким.
.foreach( a => делай_три) (с точкой) не выполняется прямо в момент когда момент выполнения доходит до
foos.Select(s=>s.Prop).Foreach(a => делай_три)
поскольку это всего лишь определение чего то, что будет выполнено потом и хз как при этом
а напрягает меня капча двача
![image.png](https://2ch.life/pr/thumb/3097760/17138018883710s.jpg)
Вот есть у меня тестовое Блазор ВебАссембли приложении. Тупо кнопка которая делает post запрос на сервер, сервер пишет в бд +1 сервер отвечает OK приложение делает +1 в счетчике и кнопка отправки запроса становится снова активной.
Сейчас WA приложение весит 6.3мб. Что дохуя если юзер будут заходить постоянно и нагружать скачиваем клиента сервер.
И вот я подумал мб если приложении будет Сервер то веб сокет соединение будет меньше создавать нагрузки?
Как б мне протестировать 2 приложения и узнать какое меньше нагружает сервер? На сколько открытое ВебСокет соединение будет загружать сервер в сравнении с загрузкой WA клиента и отправкой с его post запроса?
Бред шизофреника. За ошибками предложений даже суть не улавливается
Современный блазор хеширует твою ВА приложуху на клиенте, чел.
Разумеется, это окупается, если твоя приложуха в ВА делает нечто, что реально требует процессорной деятельности. Ты получаешь профит от толстого клиента, потому что работает юзерский процессор, а не твоей машины.
Если тебе нужно нажать единственную кнопку на страничке, то профита нет. Твой сервер без проблем справиться с соединением, нагрузкой на которое, это буквально выполнить один делегат привязанный к кнопочке в рейзор разметке.
>Современный блазор хеширует твою ВА приложуху на клиенте, чел.
Ну при заходе а страницу юзер каждый же раз загружает клиент.
>Если тебе нужно нажать единственную кнопку на страничке, то профита нет.
Ну по сути да, в приложении нет и не предвидится сложных вычислений. Максимум это сложение чисел и показ строк из БД.
Если ты планируешь все это усложнять и масштабировать, то сразу закладывай все задержки и просчитывай архитектуру заранее. Делай другой сервис, желательно независимый, чтобы невмешиваться в работу остальных. Вот один из таких сервисов, самый прожорливый на задержки сети и процессорное время, имеет смысл вынести в ВА. Пусть юзер единократно потерпит и скачает сборку ВА, зато твой сервер будет оставаться в рамках адекватной латенси, потому что в тред пуле всегда, или почти всегда, будет хотя бы 1 свободный поток.
Не каждый раз, а однократно. В самый первый раз. Восьмой блазор так работает, позволяя выгрузить пользователю компонент в ВА сборке.
> не выполняется прямо в момент когда момент выполнения доходит до
> лишь определение чего то, что будет выполнено потом и хз как при этом
> хз как при этом
Вот в этом и проблема. Ты ХЗ как оно там работает, а лезешь умничать.
Надоело в маевтику играть, пишу прямо: линк-код ("реактиве" твое) точно так же императивен, это точно такие же команды. Которые ты командуешь машине сделать. Императивишь, так сказать.
Декларативность в другом, декларативность, когда ты описываешь, что от чего зависит. И что будет для тебя совсем убийственным откровением, декларативный код описывается императивными составляющими. И функциональный тоже. Любой. От императивности в программировании никак не уйти. Всегда будут ключевые слова, команды, говорящие машине "сделай вот это, но не сейчас. а отложенно, в отдельном треде", "посчитай вот эту функцию".
![image.png](https://2ch.life/pr/thumb/3097760/17138071468540s.jpg)
>ты имеешь 4 максимум нажатия, то, в рамках задачи, тебе не нужно ВА
Ну примерно так и есть. Но подключение то будет всегда держатся открытым.
К примеру если приложение Server 100 юзеров зайдут, будет 100 подключений, юзеры сделают клик, потом так же им передастся какая нибудь инфа к примеру статья и они её будут читать к примеру 10 сек. Всё это время подключение остаётся открытым но не используется. Нагрузка в данном случае будет постоянная.
А если я буду использовать ВА нагрузка будет в момент загрузки приложения и в момент отправки HTTP запросов а сервер.
Собственно если бы у меня были деньги на vds я бы е парился просто подкинул бы монетку и выбрал. \
А с ограничим бюджетом приходится каждую копейку экономить.
А NGINX моё ВА приложение хешиует? Или каждый раз его с диска читает и выдает юзеру?
Мб есть возможность захостить ВА приложение в каком нибудь CDN?
>>132182
Ну вот старицу закрыл, потом сова захожу а её и сова загружает.
Вот мое ВА, которое загружается из локального хеша. Нагрузка на сеть пустяковая - геты за датой.
Чтобы показать статью, не обязательно поддерживать СР соединение или выгружать ВА. Можешь отправлять статику в виде компонента. Это можно сделать с помочью минимал апи или с фреймворка восьмого блазора (static SSR). Из минусов статики - 0 интерактивности (она есть, ограниченная, только при инициализации компонента). Можно компенсировать, добавив красоты в верстку с помощью жса. Придется попердолиться с ЖСИнтеропом.
Если идешь по пути ВА, то твой компонент в ВА берет на себя ответственность за интерактивное отображение контентента статьи, делая геты к серверу, когда пользователь нажимает на кнопочки. Например, чтобы перейти к следующей статье. Красоту форнта полностью обрабатывает код на шарпе и css + жс, если ты этого сам хочешь.
Не могу ничего посоветовать с моделью хостинги. В моем случае сервер есть и он всегда живой и оплаченный.
Релиз будет меньше, это банально выводится в дебаге + уже написали выше что оно кэшируется и загружается некоторое время только первый раз.
Это и есть релиз в 6мб
поумничал? молодец
>точно так же императивен
нет не императивен. его можно не называть декларативным (на деле он реактивный и конечно внутри себя он содержит императивный и какой угодно подход), но сам по себе он не является императивным.
для особо умных кто не понимает разницы приведу цитату из вики. она вполне понятна
"К примеру, в императивном программировании присваивание a = b + c будет означать, что переменной a будет присвоен результат выполнения операции b + c, используя текущие (на момент вычисления) значения переменных. Позже значения переменных b и c могут быть изменены без какого-либо влияния на значение переменной a.
В реактивном же программировании значение a будет автоматически пересчитано, основываясь на новых значениях. "
и каждый подход обладает своими особенностями, но это не значит что код состоит только из одного подхода. Однако какой то преобладает и задает стиль.
![2024-04-2309-29-40.png](https://2ch.life/pr/thumb/3097760/17138554494490s.jpg)
И если для какого-то более серьезного приложением я еще могу заморочиться с версткой, то для приложений на скорую руку верстка этих списков превращается в какой-то долбаный пожиратель времени.
Хочется видеть контрол в виде док-панели или стак-панели, но в котором можно было описание итема указать через прикрепляемое свойство (и в котором можно указать зазор между итемами, но это другой вопрос). Что-то типа этого:
> <local:CustomPanel>
> <TextBox local:CustomPanel.Caption="Width:" Text="{Binding Width}" />
> <TextBox local:CustomPanel.Caption="IsEnabled:" Text="{Binding IsEnabled}" />
> </local:CustomPanel>
и автоматом получить пикрилейтед. Есть идеи как это сделать? Дело в том, что для стак-панелей, док-панелей, юниформ-гридов нет стилей. У меня есть идея создать свой кастомный контрол, в который будут добавляться две стак-панели при помощи темплейтов в стилях.
Еще рассматривал вариант сделать какой-то конвертер значений, который бы при помощи рефлексии переводил свойства класса в словарь, а уже этот словарь при помощи DataTemplateSelector обрабатывал бы ItemsControl. Только тут две проблемы:
1) как автоматически связывать и отвязывать свойства.
2) не все свойства нужно выводить
Обосрался с примером разметки. Вместо двух текстбоксов должен быть один текст бокс и один чекбокс.
> <local:CustomPanel>
> <TextBox local:CustomPanel.Caption="Width:" Text="{Binding Width}" />
> <CheckBox local:CustomPanel.Caption="IsEnabled:" IsChecked="{Binding IsEnabled}" />
> </local:CustomPanel>
![1713865743376.png](https://2ch.life/pr/thumb/3097760/17138657446970s.jpg)
То что ты хочешь называется propertygrid и гуглится. Изучи вопрос.
О, пасиб. Это то что нужно.
![image.png](https://2ch.life/pr/thumb/3097760/17139403752990s.jpg)
Как и где можно просто спиздить дизайн?
Хотя и пизздить у меня е получается(
Сейчас css это пиздец полный
Спроси в треде HTML-программистов.
Забей, CSS проектировали для бездумного макакинга и вникать в него это дело непродуктивное, просто делай потом если чё перепишешь.
![1713957254451.gif](https://2ch.life/pr/thumb/3097760/17139572552580s.jpg)
Ты-то чего триггернулся?
> Оказывается придумать а потом еще и сделать так как придумал дизайн пиздец какая сложная задача(
Теперь ты не будешь кудахтать на Артемия Лебедева, что он получает огромные бабки за рисование двух прямоугольников?
Та не.
Если делаешь один - все вполне нормально.
Вот когда подключается пара других человек, которым ты объясняешь, а они дохуя хотят проявить творческую жилку и хуярят хуй пойми что - вот тогда да. Пизда. И проблема в том что на ревью же не завернешь, если не собирать и смотреть что ж там эти наверстали.
В этом большая сложность. И как спастись от нее - хуй его знает.
CSS - учится за 3 часа, если чо.
![image.png](https://2ch.life/pr/thumb/3097760/17139951244550s.jpg)
Есть такие вот фреймворки
https://github.com/ant-design-blazor/ant-design-blazor
https://github.com/radzenhq/radzen-blazor
https://github.com/microsoft/fluentui-blazor?tab=readme-ov-file
https://tabblazor.com/
Объясните зачем это всё нужно?
Там же дефолте кнопочки-таблички. Ну да готовые кнопочки, но бля а если они хуево сделаны?
Я вижу единственный профит в использовании это в интерпрайзе без особой ебни клепать стандартны UI про которое пользователь скажет "норм", и это в случае когда у бекендера просят сделать еще и фронт, а он такой ну ок ебану как могу а могу только так.
В чём я не прав?
На клаве е работают копки так что е обесудьте, печатая в помощью экрраки+ ерабочей клав.
Затем, что делать нормальную библиотеку своих компонентов - пиздец трудоемкая задача, особенно, если у вас нет отдельного подразделения для вротендеров-десигнеров, либо если это подразделение собрано из вчерашних студентов.
Ну так вот. А показывать сырой ХЭТЭЭМЭЛ/Обвешанный бутстрапом - моветон, ты показываешь это заказчику/менеджерам, они морщатся и решают что вы хуйней страдаете, хотя может быть все остальное охуенно.
Так вот. Такие вот хуевины - позволяют взять 1-2 вротендеров, чтобы они биндили карточки-таблички к тому что бек отдает и это минимально было ок для глаза, а когда настанет час X, и продукт будет достаточно развит, приносить деньги, и будет то самое отдельное подразделение смузихлебов фронтендеров-дизигнеров, которые сидят, хуярят презентации и поясняют как margin: 5px улучшит восприятие пользователями наполнения - тогда это все легко выбрасывается и вы пилите свое.
Эх. Блядь. Как у меня горит что девекспресс - санкционный. Это литерли была серебрянная пуля чтобы хуйнуть быстро все че надо, потом можно чутка обмазаться какими-нибудь чартами красивыми и либой для анимашек - и все текли. А сейчас - всякое попенсорсное, которое больше самому допиливать до вменяемого состояния. Пиздец как горит.
> троллит
Значение знаешь? Пойми, дурачок, ты буквально спрашиваешь, почему кирпич хуже пентхауса. Осознай всю нелепость вопроса.
А вообще, я тут поресерчил и наткнулся на CommunityToolkit. У них есть классная штука - Мессенджер. Все классы, наследуемые от ObservableRecipient могут как получать так и отправлять сообщения через него под капотом используются слабые ссылки. Таким образом можно в родительской вью модели подписаться на запросы навигации, и в других вьюхах просто слать реквесты, и не нужно писать тонны бойлерплейта. Пожалуй теперь буду проектировать архитектуру на его основе.
Из кирпичей авалонии можно построить пентхаус красивее и эффективнее впф-параши прибитой гвоздями к венде. Осознал. Спасибо.
Тут внезапно назревает десктопный проект.
Так вот. Я тут понял, что нихуя не понимаю за архитектуру десктопа. Единственное что хочу, чтобы был модульным, и можно было докинуть dll и новая фича впиндерилась САМА. Ну, типа видел похожее во фрутилупсах, когда игрался и кажется пиздец крутой хуйней.
Вот.
МБ кто-то поделится проектами опенсорсными на дотнете под десктоп, которые, так сказать - ОБРАЗЦОВЫЕ. Чтобы можно было поглядеть, че там да как, чтобы бест практис перенять.
не слабые ссылки, а дефолтный общий мессенджер если не передал ему другой тип мессенджера или конкретный.
мыльные они
и, в отличие от впф, чинятся так себе. Поэтому они в авалонии и крупнее ибо мыло.
За шрифты там отвечает встроенный пакет harfbuzz, соотвесна, если тебе что-то не нравится - настраиваешь его. Я с шрифтами проблем не вижу.
А ты смешной. Во первых для его настройки придется самому компилять авалонию, а во вторых, сколько не настраивай, а directwrite из него не сделаешт.
Во-первых, повторюсь, я не вижу мыла.
Во-вторых, ничего компилять не нужно. Идёшь в документацию harfbuzz и разбираешься. Я вместо тебя этого делать не буду.
В третьих. Harfbuzz используется отдельно без авалоний всяких, это нугет-пакет, и пользователи не жалуются. У одного тебя мыло. Я делаю вывод, что ты несёшь хуйню.
![image.png](https://2ch.life/pr/thumb/3097760/17142225757500s.jpg)
То, что ты пиздоглазый тупой сектант все уже поняли. Но я все же потрачу время, и покажу наглядный пример всратых шрифтов в авалонии.
>Во-вторых, ничего компилять не нужно. Идёшь в документацию harfbuzz и разбираешься. Я вместо тебя этого делать не буду.
Ты правда какой-то блаженный, если не понимаешь, что для изменения таких вещей как рендеринг необходимо залазить в самые кишочки фреймворка
>В третьих. Harfbuzz используется отдельно без авалоний всяких, это нугет-пакет, и пользователи не жалуются. У одного тебя мыло. Я делаю вывод, что ты несёшь хуйню.
Конечно не жалуются, ведь шрифты рендерит не harfbuzz, тупой ты ебанат. А вот жалоб на хуевые шрифты в Skia в том числе в хроме вагон и маленькая тележка. Но гуглу поебать, на мобилках то норм.
>Помогите, у меня сломался впф! Все кнопки как в виндовс 98!
Так это же охуенно. Я бы на твоем месте пытался выяснить как это специально повторить.
Норм статья? Ценам можно доверять, как по вашему опту то?
Ну хз, после майских сделаю дамп венды. Чем дампнуть, чтобы ИТТ выложить на анализ?
А что тебя смущает.
Я бы только за MVP цену снизил раза в 2, а за готовый продукт наоборот поднял в 1.5-2 раза.
никоим образом.
Более того, если ты выставишь у себя на венде DPI выше 100% (от дефолтного, в терминах венды) ты охуеешь от того, что большинство из них превращаются в ещё более лютое мыло.
И только православный винформс, написанный ещё дидами, уверенно держит ровные линии без мыла.
ну так в формсах другой тип рендера
а вообще зачем выставлять больше дефолтного?
если ты про 4к дисплеи и всякие ретины то WPF имеет средства для настройки рендера
в далекие времена написал заглушку
TextOptions.SetTextFormattingMode(window,
Dpi >= 144 ? TextFormattingMode.Ideal : TextFormattingMode.Display);
TextOptions.SetTextRenderingMode(window, TextRenderingMode.ClearType);
правда не проверял на ретинах ибо нет их у меня, так что делал больше для фуллхдшных, а на ретинах и так хорошо же.
Как я понимаю если прямо сейчас вкатываться в юньку у меня в перспективе будет только лепить гиперказуальное говно для галеры, где меня заебут переработками? Стоит ли в таком случае вкатиться в вебразраба и уже оттуда заниматься своей хуйней? Что вообще думаете про геймдев нынче?
Места в вебе больше. Да и в целом у тебя выбор не веб или гейдэв, а бизнес или гейдев
Геймдев говно с низкими зп и переработками. Веб единственное нормальное направление. Но после тяжелой рабочей недели у тебя уже не будет сил сидеть на выходных и ковырять свою игру, имей в виду.
Смотря какая неделя и где работать. У меня порой бывает очелло, а порой даже желание что то на выхах попилить остаётся
>Но после тяжелой рабочей недели
Я не планирую тяжело работать. Планирую найти работку на парттайм или ненапряжный проект. В ущерб своей ЗП и перспективы конечно же.
Было бы всё так просто я бы тоже .5 залетел а не фуллтайм
Единственный адекватный вариант работать парттайм - это устроиться на фуллтайм, делать свою работу за половину времени, а остальное время чилить или заниматься своими делами. Но чтобы такое получалось, надо быть не начинающим, а очень крутым специалистом.
>Цель - ненапряжно работать, а в свободное время лепить свою игрушку(подтянуть рисование, в 3д потыкать).
Есть вариант. Устраиваешься на какой-нибудь завод за 30К, там периодически подкручиваешь для теть срак из бухгалтерии какое-нибудь древнее говно на .NetFramework, остальное время гоняешь чаи и пилишь свою игрушку.
а ведет/вел кто план-график задач?
просто хочу составить для обучения и я как то затерялся.
для диплома по С# надо что то сварганить по базе данным (тут бы подошел наверн больше php, но мне в будущем для геймдева не особо нужен будет) и статью написать.
> но мне в будущем для геймдева не особо нужен будет
... опыт кодинга не зависит от языка. Жаль что ты этого не способен этого понять на своём уровне, и вдвойне жаль, что ты не способен поверить в это. Ты 20 лет будешь делать неинтересную тебе хуйню, на нелюбимом тобой языке, чтобы через 20 лет понять, что тот анон был прав 20 лет назад, который написал, что...
Чем копать?
>а ведет/вел кто план-график задач?
Если ты под 'план-график' подразумеваешь, что-нибудь вроде диаграмм Ганта, то в соло это нахуй не нужно. Когда лидом станешь, тогда и научишься. Для разработки в одного или миникомандой в 2..3 человека достаточно простейшей канбан-доски.
>... опыт кодинга не зависит от языка.
В большинстве случаев зависит. Каждый язык прививает свои привычки, обусловленные либо спецификой, либо особенностями/ошибками дизайна языка. И очень часто те кто пытаются пересесть с одного ЯП на другой перетаскивают все эти особенности за собой и нужно время (иногда достаточно продолжительное), чтобы от них избавиться и переключиться на другие парадигмы.
Говорить о том, что "язык не влияет" можно только в случае хорошей теоретической и практической базы в самих основах информатики.
>Говорить о том, что "язык не влияет" можно только в случае хорошей теоретической и практической базы в самих основах информатики.
Чего у большинства тех кто сейчас изучает программирование нет. (забыл дописать)
Делаю ТГ бота и админку к нему в web. Норм идея сразу из приложений обращаться к бд?
Или делать микросервис который бы писал и читал бд? Что то типо TgBot+WebApi_Bd+WebAdmin
>Если 2 приложения пишут и читают с одной sqlite бд, не будет ли проблем?
Multiple processes can have the same database open at the same time. Multiple processes can be doing a SELECT at the same time. But only one process can be making changes to the database at any moment in time, however.
Вообще, в принципе, плохая идея подключать к одной БД (любой ) более одного приложения.
Максимум какой-нибудь мониторинг поверх навешивать, но и то это только на уровне select-ов будет.
Что для тебя приложение?
Две апихи одна для интеграций и а другая для фронта это разные? А два+ инстанса одного сервиса при горизонтальном масштабировании? Что на счёт коннекшен пулов которые повсеместно?
Где ты вообще услышал такое?
sqlite плох для активной многопоточной записи.
не знаю как реализация от майков, но стандартная подвержена проблеме
1 первый поток пишет
2 второй поток видит локед и ждет
3 первый поток освободился пришел еще один - база свободна, начинает писать
4 второй поток (из пункта 2) проснулся и снова проверяет можно ли писать - а там локед и он снова ждать
в итоге все влезают впереди второго потока и у того истекает таймаут
если меньше писать, увеличить таймаут, то проблема будет иметь меньшую вероятность встречи, но по хорошему нужно писать в порядке очереди. И если даже для одного приложения это неудобно, то для двух тем более.
>Две апихи одна для интеграций и а другая для фронта это разные?
Ну я хуй знает, как это у тебя построено, может у тебя это одно приложение, а может и разные.
Если же ты под "API для интеграций" для интеграций, подразумеваешь непосредственный доступ к БД - земля тебе пухом, братишка.
>А два+ инстанса одного сервиса при горизонтальном масштабировании?
Не вижу проблемы. Горизонтальное масштабирование подразумевает, что экземпляры приложений будут идентичными. По сути - то же самое, что запустить несколько потоков в одном приложении.
А там разговор про разные приложения с разным функционалом, когда каждое приложение творит в БД свою собственную хуйню.
Опять же, я не говорил, что этого нельзя делать или запрещено, я сказал, что это плохая идея. Т.к. возможные сайдэффекты в будущем в большинстве случаев перевешивают пользу сейчас.
В контексте пишут-читают.
Делай третье приложение, которое полностью владеет базой.
Далее. Разбей апи этого приложения на запись-чтение.
Запись - выполняй в одном потоке, через очередь.
Чтение - через WAL можно нормально организовать из пачки потоков, если не критично, что какие-то данные могут устареть, если критично - таки через тот же поток читай.
Далее. С SQLite - неочевидно, но даже если ты там кольцевой буффер намутил - эта хуйня не умеет чистить сама себя, что логично. Потому - тебе периодически надо Vacuum дергать, либо собирать SQLite с автовакуумом, иначе, через полгодика-годик оно тебе все место спокойно сожрет, если в базу активно пишут-удаляют.
Знал бы ты как я svn ненавидел из-за раздувания sqlite файла до размеров в гигабайты. А ещё и тупейший вакуум с подходом stop the world
А я знаю. На одном из мест работы - это чудо эксплуатировалось активно.
![image.png](https://2ch.life/pr/thumb/3097760/17147380678340s.jpg)
>>142108
>>142123
>>142145
>>142563
Всем спасибо.
Решил всё такие MVP делать в одном приложении что бы было быстрее, потом если у бота будет популярность переделаю на 3 приложения.
Вот у меня вопрос по кешу
Есть
IMemoryCache cache;
И еще есть
MemoryCache cache;
В интерфейсе нету Count а в классе есть. Это как так? Что юзать? Нихуя не понятно, я начал чета юзать класс MemoryCache. Там типо делается так Get(key) и получаю object который потом нужно привести к к своему типу, чета я подумал что так будет долго и написал свой "кей" Dictinary<long,MyClass>. В кеше нужно юзать я так понял TryGetValue но его в классе нет он в интерфейсе, корочи нихуя не понятно.
И еще я сцыкнул конструкции
cache.TryGetValue(id, out User? user);
Вот у меня есть класс Storage он Singleton, в нем тот самый кеш. Таски обращаются за инфой в хранилище и хранилище возвращает к примеру User? user, что будет если первый таск выполнит строчку cache.TryGetValue(id, out User? user); далее пойдет дальше, а вэто время второй таск тоже выполнит эту же строчку, не изменится ли значение User? user?
Сейчас у меня пикрил, нужно ли там лок вставлять?
>В интерфейсе нету Count а в классе есть. Это как так?
а вот так. клиенту для работы с кешем нужно читать и класть в него (что и предоставляет интерфейс). Ему знание Count не нужно.
>TryGetValue но его в классе нет он в интерфейсе
такого быть не может. если есть в интерфейсе - есть и в классе. Иначе класс просто не сможет реализовать интерфейс (и не скомпилится)
>Сейчас у меня пикрил, нужно ли там лок вставлять?
угу, будет двойное выполнение и нужно от этого защищаться. Так что нужно либо лок, либо кешировать Lazy<T> (что впрочем тот же лок только в профиль)
> если есть в интерфейсе - есть и в классе
В какой то версии ебанулись и ввели дефолтную реализацию в интерфейсах
которая ограничена тем что публично. Так что формально такие вещи существуют, но написать ты такой метод не можешь - у тебя просто не к чему внутри него обратиться для его работоспособности.
Чем такой код хуже стандартной фигни с OnPropertyChanged в каждом классе который реализует INotifyPropertyChanged?
Хм. Я умный получается?
Просто сейчас - начинается проект с десктопом, и я чет курю мануалы, как там в шарпах писать этот десктоп. Меня смутило что в туториалах в каждом классе этот OnPropertyChanged. Десктоп трогал последний раз, когда WinForms были актуальны.
Ну, да, выходит так.
Твой метод требует оптимизации чтобы меньше рефлексировать каждый раз, а также не учитывает что значение не изменилось и нечего шуметь (на деле это должно быть настраиваемое)
А так - вот эту писанину лучше доверить Fody или еще чему нибудь вон как в комьюнититулкит.
Тем, что нужно использовать this, что бред само по себе, когда можно просто реализовать в родительском классе.
Ну и в целом, рефлексия это медленно и еще у тебя нет проверки на равенство
Я не писал апих на шарпе, ток лабы в унике.
Сейчас хочу перебраться со своих пердей, где есть дноработка на ноде+реакте в дс1/2 и пересесть на асп нет.
Так вот, подскажите, пожалуйста, что наиболее часто юзается в норм местах? В плане брокеры, grpc, и прочие штуки типа yarp.
И если есть какой-то убергайд в виде видосиков, курсов или еще чего, приближенного к реальному положению дел, буду очень признателен.
заебало педалить всякую рандомную хуйню в черную, хочу спокойно педалить че-то одно и в команде а не в одно ебало :c
> убергайд в виде видосиков, курсов или еще чего, приближенного к реальному положению дел
Видосы Шмачилина на ютубе.
- Создать MVC веб-приложение, которое позволяет пользователям вводить и хранить документы в базе данных PosgreSQL;
- Документ должен представлять собой понятие - Договор на оказание платных услуг, содержащий в себе номер и дату договора, а так же возможность указывать строки (смету) - название и цена.
2. Взаимодействие с базой данных PostgreSQL:
- Настроить Entity Framework для работы с базой данных;
- Настроить обращение к базе данных из приложения на ASP.NET. Документ должен передаваться в хранимую процедуру в форме XML, результатом должна быть сумма цен всех строк документа.
Выглядит так будто нужно просто из БД в UI вернуть сумму строк, но причём тут XML? Прямо в процедуре брать данные из таблиц и превращать их в XML, просчитывать сумму и возвращать в .net приложение её?
Или что, dto документа из UI слоя превращать в XML и передавать в БД? Но причём тут тогда результат...
Может кто мысль подтвердить или новую подкинуть? Сам виноват, что не уточнил, теперь боюсь им писать.
Ну нахуй. XML это либо госы либо ебанутый легаси на дотнет фреймворке, что из этого хуже стоит ещё подумать
уточняй. Ничего плохого не случится.
если это так сократили "у нас выгрузка в виде xml туда сюда пук вот и база данных, готово", то нужно уточнять. ТЗ должно быть ясным. Если они считают что тз ясное и вопросы не нужны - неча тебе там делать.
А если в хранимке хмл крутить, то это дичь - неча тебе там делать 2.0
>теперь боюсь им писать.
Не бойся. Очень часто в тестовых заданиях оставляют непонятки, как раз на тот случай, чтобы посмотреть умеет ли кандидат уточнять требования по ТЗ.
Если спросят, почему сразу не уточнил, можешь сказать, что занят был всем остальным функционалом, который понятен.
>>146561
>Ну нахуй. XML это либо госы либо ебанутый легаси на дотнет фреймворке, что из этого хуже стоит ещё подумать
Ты удивишься, но до сих пор половина бизнеса и весь банкинг на xml-ках работают. Многие причем просто пересылая их в виде файликов друг-другу через фтп или каталоги на серваках.
Конечно такая дичь, как запихивать xml-непосредственно в sql, встречается крайне редко и это действительно долбоебизм. Но сам формат xml - это база.
![16721289485620.gif](https://2ch.life/pr/thumb/3097760/17150084696180s.jpg)
>>146661
> Разве не об этом я и написал?
Ты написал, что xml - это либо госы, либо легаси.
А я написал, что весь бизнес и почти весь банкинг на них работает.
Других вакансий всё равно в моём городе пока нет, либо эта, либо "инженер-программист" на нпп/заводы, выбирать особо не приходится.
> но делать такие операции на стороне бд это немного шизофрения.
Че эта?
Удобно. Допустим, настроил триггеры, у тебя этот XML сразу в БД формируется. Сверху можно еще вебхуки дергать по завершенюи транзакции, чтобы результирующий XML сразу отдавать куда надо. Одни плюсы короче. Ноль минусов.
Удобно. Хз только, зачем вообще тогда нужен дотнет, если можно всё делать на хранимках, как деды.
Так говоришь, как деды, будто что-то плохое.
А дотнет нужен потому что можно бысто круды хуярить, плюс - всякие там идентити, двухфакторные аутентификации, ну, там, ты понял.
Просто если вопрос про интеграцию дохуя всякого с одной базой - ну реально оказывается часто что БД это самый удобный узел системы, через который можно все со всем подружить.
>Других вакансий всё равно в моём городе пока нет
Советую тогда не гнать лошадей, а сделать все пусть и неторопливо, но качественно, уточняя непонятные моменты (в меру конечно).
У меня в свое время товарищ будучи с нулевым стажем, не зассал и залетел на джун-плюс позицию, просто потому что основательно выполнил тестовое. Даже с учетом того, что он сделал его за две недели вместо одной как просили, но он задавал нормальные вопросы, проявил инициативу, попросил отсрочку с прицелом не на то, что он не успел, а что хочет сделать нормально.
>Одни плюсы короче.
Есть один минус. Тот кому придется это дорабатывать за тобой - проклянет тебя, выследит и выбьет из тебя все дерьмо.
Нашел еще решение ещё лучше, вместо использования dips включил пиксели
Жава и шарп на рынке - занимают +- одинаковое пространство. Жава была сильно популярна на мобилках, пока не появился котлин.
.NET - для серверов считай второй по популярности стек, после LAMP
По кол-ву работы, если в мире - +- одинаково. Если в РФ, тут как обычно - надо распилить осводить бюджет, потому переписываем старое-негодное на ПХП/Жаве на что-то более модное-молодежное, похуй что потеряем половину функционала, зато модное ГОвно или еще что-то.
В РФ шарп активно применяется в проебизнесах, вузах, производствах и как клей чтобы несколько систем друг с другом сдружить.
Плюс. На шарпе есть юнька, которая конечно обосралась, но все еще замены ей внятной нет.
>перекатиться в европку/швятые потом тяжело,
Язык программирования будет одним из твоих последних и незначительных препятствий при переезде.
>и вообще работы нормальной нет, одно легаси говно. Это близко к правде, или это завистники слухи распространяют?
Работы дохуя, но не для новичков.
Насчет легаси его полно и на шарпе и в джаве. Но есть ньюансы (чисто мои наблюдения, не претендую на истину). В джаве легаси размазано ровным слоем по всему рынку и ты с ним столкнешься практически везде куда бы ни пошел. В шарпе же легаси сосредоточено в отдельных отраслях - промышленность (те самые заводы), прикладные области, десктоп, древний internal web и т.д. Если идти куда-нибудь в финтех, B2B, продуктовые галеры, то там большую часть уже переписали на .Net6 и под линукс/контейнеры, есть места где уже в 8-й переходят. В шарпе как раз таки проще чем в джаве относятся к "выкинуть старое - написать новое", т.к. переезд со старых версий относительно не болезненный (опять же по своему опыту), плюс он в принципе без особых проблем ложиться на модное нынче импортозамещение (на те же российские линуксы с винды переходить на раз-два)
Смотря что ты подразумеваешь под API. Делать GET-запрос и в ответ получать image/png - это API? Или там шизозадание, где картинку надо закодировать в Base64 и передать внутри жсона?
А в чём шиза?
Base64 гарантирует корректную передачу по сети.
Жсон универсальный формат, прочитается в любой среде на стороне получателя.
Шиза-то в чём?
загрузи гигабайтный файл - и десериализуй на стороне получателя чтобы достать файл. И вопросы отпадут
Я што дурак гигабайтный файл целиком грузить? Я его разобъю на фрагменты, и base64 поможет мне их собрать обратно на стороне получателя.
грузить во много запросов вместо одного? ну ты даешь.
>>148365
Чел, половина учебных проектов в веб-разработке - это буквально аналоги какого-нибудь онлайн маганзина (страничка каталога или экран корзины), или какой-нибудь еще херни с показом картинок (по подиночке или каруселью) и т.д. Если ты этого не знаешь или не можешь нагуглить, то слишком рано ты за поиск работы и тестовые зядания принялся.
Ну покурил, там так и есть, весь текст разбит на отрезки текста с одинаковым форматированием. Но из структуры формата не ясно, как все таки реализовать выделение
В чем проблема просто маркдаун использовать?
Во-первых, сам формат оч простой.
Во-вторых, при желании пользователь может открыть без всей этой ебатории с какими-то там редакторами.
Но если совсем простенький текстовый редактор, то вообще - можешь обойтись простым RichTextBox, тот все что тебе надо умеет. Тебе сверху накидать кнопок и заменять текст в выделенной области на те какие тебе там надо.
Анон, проблема не в самом формате, тут я уже определился, проблема именно в процессе работы с текстом. То есть как хранить свойства во время работы, чтобы все работало быстро. И желательно логика была как можно проще.
А richtextbox увы, с одной стороны слишком сложен, а с другой в нем много всего прибито гвоздями. Я сейчас для рендера текста использую DirectWrite (IDWriteTextLayout), там куда больше возможностей для кастомизации текста, притом всю сложную работу вроде bidi и переноса строк он делает сам. Мне остается только скармливать ему текст и устанавливать свойства для отдельных промежутков. Плюс мне нужна высота строк для отрисовки линовки.
А markdown насколько мне известно не поддерживает толком форматирование разные шрифты, размер и тд текста.
![0ac13798e2e9cf0907a15e794a891e2a.jpg](https://2ch.life/pr/thumb/3097760/17152395176380s.jpg)
Собственно. Встала проблема. А как багрепорты и вообще вот это все получать?
Типа, от пользователя - не дождешься, чтобы он пояснил, че он вообще делал. Если кто-то и обращается, то в духе: ничерта не работает, ну вы и говно сделали, чините. Тестировщики - чуть лучше, но не сильно, типа да, описывает проблему, описывает шаги, но не повторяется проблема.
В общем. Я не хотел, но видимо придется впиндерить телеметрию. Чтобы в случае чего - можно было больше инфы иметь.
Но тут несколько проблем.
1. Я считаю что эт не оч этично. Типа, даже если пользователь дал согласие.
2. Как эту телеметрию делать правильно - я не ебу. Типа, ну, допустим, будет просто собираться какой-то дамп со стейтом и улетать на сервер. Хорошо, но типа это сразу сервер нужен дополнительный, нужно как-то это анализировать удобно, ведь без нормальныйх средств, это все равно что текстовые логи попросить, просто большой кусок данных, который хуй проанализируешь нормально.
В общем. Я прошу советов мудрых. Как таки упростить мне жизнь как разрабу, чтобы баги в проде легче находились и хотя бы понимать последние действия пользователя, которые выявили багулину.
![1715243297501.png](https://2ch.life/pr/thumb/3097760/17152432988070s.jpg)
А как это сделано у других? Вот посмотри и повтори. Чо там сложного?
![image.png](https://2ch.life/pr/thumb/3097760/17152647931410s.jpg)
А что собственно развивать?
Твой текст - некий документ.
Значит что? Значит тебе нужна некая объектная модель того, как этот документ представлен в приложении.
Ну, а как быстро ходить по объектной модели документа, менять что-то в ней, совершать классические операции всякие типа добавить к куску документа стиль и прочее? Правильно, представить в виде дерева объектов. Корнем - является этот самый документ, а дальше - какие-то твои объекты, которые описывают структуру документа, какие стили к чему применяются, какие данные лежат где и прочее. Так ты просто можешь найти текущий кусок документа, и при редактировании - просто добавить либо данные, либо новую ноду, в которой лежит стиль который тебе нужен и прочее.
Можешь не изъебываться со своим форматом, а взять какой-нибудь готовый. В любом случае в твоем приложении он будет представлен в виде дерева, потому что операции с деревьями это быстро, это просто, это удобно для тебя как разработчика.
>потому что операции с деревьями это быстро, это просто, это удобно для тебя как разработчика.
>операции с деревьями
"Но как же так, мне же сказали, что алгоритмы не нужны..."
Чет, слегка ржу.
Пользуюсь хешсетом и словарем не вникая в реализацию (и тем более не пишу свою)
Мне пора уходить из профы?
>Мне пора уходить из профы?
Пиздовать нахуй, мелким и быстрым шагом. Только не по тем причинам которые ты указал, а потому, что не можешь в юмор, слишком туп, чтобы за контекстом беседы следить и задаешь дурацкие вопросы.
Справедливости ради, горутины не совсем таски. Плюс - сами по себе эти горутины - ну, пиздец какая удобная залупень. Я серьезно хотел бы чтобы что-то такое было в шарпе.
Типа пишешь метод как обычный синхронный, но при желании - берешь и запускаешь его как асинхронный, без всякой ебанины. С тасками - ты обязан сделать выбор: либо асинхронщина, либо синхронщина.
а я бы не хотел. ничего не знаю про го, но знаю про котлин. и за "выглядит как синхронный код" приходится платить высокую цену с "работа с исключениями ад" и с тасками на 10 порядков проще.
Шарпаны, есть какие-нибудь нормальные печатные материалы по OpenTelemetry в разрезе Asp.Net Core. Только что-нибудь последовательное, где слона едят по частям. А то в большинстве случаев берут приложение, накидывают в него сразу кучу говен в виде метрик, трейсов, логов и т.д., потом запускают дашборд - "смотрите, как заебись". А что из этого зачем и что делает не очень понятно.
>Шарпаны, есть какие-нибудь нормальные печатные материалы по OpenTelemetry в разрезе Asp.Net Core.
?
Знак вопроса забыл.
![image.png](https://2ch.life/pr/thumb/3097760/17154196006800s.jpg)
Для себя я оправдывал это вот чем. Типа юнит-тесты же. Вот. И вот таким макаром - можно было тестировать, что все правильные зависимости проставлены, все такое. Плюс, что приложение правильно стартует, правильно останавливается. Но все равно выглядит как страдание хуйней ненужной. Но желание переписать чтобы не как у других было - никуда не девается.
>Как перебороть желание
Да не, норм все. Я тоже подбным страдаю наслаждаюсь постоянно. Только мне поебать на юнит тесты, я хочу маленькую компактную точку входа из которой вызываются нужные расширения для подключения нужного функционала.
![изображение.png](https://2ch.life/pr/thumb/3097760/17154453812850s.jpg)
Раз выдалось время на выхах решил замутить один сервис и в рамках него упороться в otel.
Курю доку майков, доку отеля, сорсы на гитхабе и ещё этот видос глянул https://www.youtube.com/watch?v=bYc7u9HFG0s
С виду должна получиться пушка гонка
![image.png](https://2ch.life/pr/thumb/3097760/17154552255310s.jpg)
Консоль в дебаггере в помощь
nuget - JsonDiffPatch.Net
Может выдать json со списком отличий свойств одного объекта от другого. А ты уже с этим json-ом можешь делать, что хочешь для удобства представления инфы. Еще умеет сравнивать объекты разных типов по одноименным свойствам.
По итогу сам отел взлетел с пол пинка с метриками и трейсами, а вот выбрать куда писать то ещё приключение.
По итогу остановился на егере (query и collector. agent решил не поднимать) с эластиксёрч стораджем (разбираться с не очень подходящей под это кассандрой нет желания). Сам эластик у меня уже есть, но давно хотел заменить на опенсёрч, надеюсь jaeger-collector не будет выёбываться
А кто мешает присобачить к интерфейсу метод расширения
bool XXXMethodName(this IMyInterface interface, string[] arg)
{
try {return interface.InterfaceMethod()}
catch {return null}
}
Что метод расширение, что метод в интерфейсе - никто из них не может обращаться к приватным полям класса.
Да просто в определенном месте кода вызывается Invoke у делегата, который в свою очередь вызывает выполнение привязанных методов.
ну это тебе нужно копать исходники как происходит взаимодействие с фреймворком. Только зачем оно надо.
Который привязан к событию.
Примерно так, лол.
class FrameworkElement{
private void Load()
{
DoInternalLoadStuff();
var handler = Loaded;
if(handler != null) handler(this, CreateLoadedEventArgs());
}}
Я про что говорю. Вот допустим, у меня есть модель:
class Project(string name, string description, DateTime created, List<ProjectTask> tasks);
class ProjectTask(string name, string description, List<Employee> employees, TimeSpan estimatedDuration);
class Employee(string Name);
Вот, я хочу создать в проекте задачу и добавить туда сотрудников.
Но логика такая, что я не могу добавить сотрудника, который уже в другом проекте и у него по таскам - выходит так, что рассчетное время больше чем рабочих часов за время длительности проекта.
Ну. Вы поняли. Типа, если сотрудник и так загружен - логика такая, что нельзя незначить серху задачу.
Вот допустим - я делаю это в Project, как корневой сущности. И выходит, что я должен из одного проекта иметь доступ ко всем проектам, еще я должен иметь постоянный доступ к БД, чтобы вот эту вот логику реализовать.
Но ведь получается бредово же. Для другой операции с этой моделью мне не нужна никакая база, но я ее все равно пропихну. Или ок, я буду в методе требовать базу, но тогда тот кто дергает - должен предоставить эту базу. Короче. Выходит в любом случае какая-то хуйня.
Просто я почему спрашиваю. Мне скучно делать анемичную модель. Но вот попытки сделать богатую = выливаются в то, что становится тупо неудобно кодом пользоваться.
Как быть? Кто-нибудь пробовал на серьезных щах богатую модель делать, чтобы оно работало нормально?
>Но логика такая, что я не могу добавить сотрудника, который уже в другом проекте и у него по таскам - выходит так, что рассчетное время больше чем рабочих часов за время длительности проекта.
Выглядит так, что во первых ты пытаешься запихнуть дракона в ослицу, т.е. это совсем не их логика. Во вторых как будто для такого нужны собственные сущности над ними. Типа "рабочая загрузка" или общий "план-капкан" или еще что-то, что по иерархии имеет доступ ко всему что в него будет входить (проекты, работники их загрузки и т.д.)
>>155473
>Просто я почему спрашиваю. Мне скучно делать анемичную модель. Но вот попытки сделать богатую = выливаются в то, что становится тупо неудобно кодом пользоваться.
>Как быть? Кто-нибудь пробовал на серьезных щах богатую модель делать, чтобы оно работало нормально?
Ну вот потому обычно реализации DDD у многих и выглядит как говно, т.к. сначала нашлепают анемичных моделей, а потом начинают вносить в них логику, которая "типа" им подходит или близка им по смыслу. А идти это должно в первую очередь от архитектуры и от грамотного ТЗ где прописываются все взаимосвязи и сценарии и ограничения. Но т.к. нормальные аналитики это редкий зверь, архитекторы, чаще всего просто бывшие аналитики имеем стандартные проекты ложащиеся на обычную слоеную архитектуру с анемичными моделями. Просто потом приходит ПМ, лид или еще кто и "пацаны у нас теперь все по ДДД, го запихивать весь service layer в домен"
Ну. Допустим, в моменте с проектированием, я согласен.
Но вопрос про то как инфраструктуру и слой приложения на это натягивать.
Вот теперь у меня есть некий "Календарный план". Ок. Ему все равно же надо иметь доступ к БД, либо какой-то репозиторий/юнит оф ворк ему скармливать, либо тот же сервис, чтобы уже можно было что-то из этого делать. И получается, что я либо раздуваю конструктор, либо кучу параметров в метод передаю, либо создаю мусорные классы, для передачи разом настроек и зависимостей для этой операции.
Ну честно говоря я х.з. как оно прям правильно. Но то с чем я работал по сути все равно имело отдельный DAL слой с репами и uow. Репы были тупыми, но могли работать со спецификациями. А спецификации были частью доменного слоя. Ну и сервисный слой так же сохранялся. По сути логика оказывалась размазанной между моделями/спецификациями и сервисами их обслуживающими.
Опять же всякие валидации тоже были либо в конструкторах моделей, либо в виде отдельных валидаторов, так же привязанных к сущностям.
>Task.Run(() => MyFunctionAsync(this.MyProperty));
Но такой вариант исключений не вызывает:
>bool myProperty = this.MyProperty;
>Task.Run(() => MyFunctionAsync(myProperty));
Исключение в первом случае:
>System.InvalidOperationException: "Вызывающий поток не может получить доступ к данному объекту, так как владельцем этого объекта является другой поток."
И почему исключение говорит о другом потоке, когда речь идет об асинхронной функции?
Хорошо, а как меняет ситуацию тот факт, что я свойство сохранил в переменную и передал ее в качестве параметра асинхронного метода?
Ведь переменная создана не в том потоке, что и выполняемая задача, а в том потоке, что и свойство. Что поменялось?
Свойство это ссылка на метод, переменная полученная из свойства это уже ссылка на объект.
Task.Run(() => MyFunctionAsync(this.MyProperty));
сначала запустится задача (на пуле потоков), задаче будет выделен поток и уже потом пойдет чтение this.MyProperty и ругается именно get метод свойства MyProperty потому что программист в него проверку запихал
никакой шарп никакие потоки не проверяет.
У меня иерархическая структура.
Но т.к. поиск всех потомков рекурсивно долго - я делаю хак: в строке храню путь к родителю. Получается в духе 1.2.3, 1.2.4, 1.2.5
Вот.
Это оч сильно ускоряет поиск дочерних узлов. И работу с ними в общем случае.
Так вот. Теперь я хочу при изменении у родителя родительского узла - всем потомкам изменить.
На базе триггеров - это делается изи. Просто триггер на упдейт и все. Кайф. Красота. Все так же быстро и красиво. Одной транзакцией - хуяк и хоть миллион записей проапдейтили.
Но мы же говорим про ЕФ и независимость от базы. Так вот. Делать это на уровне приложения - это пиздец заеб, медленно и вообще, ебатория, если дерево здоровое.
Есть ли какие-то паттерны как не делать триггера но чтобы было быстро? Переход на носкуль не предлагать.
Просто вот я фуллстек, и на фронте как-то само собой получалось, что чтобы не возиться со всей этой ебаторией с миллионом папочек - ты в определенный момент решаешь: вот у меня папочка, в ней ВСЕ что мне нужно. И было на самом деле удобно.
Но на бекенде я как-будто боюсь отойти от того как учился все это время делать. А потому - по шаблону: App.Application, App.Core, App.Infrastructure, App.Hosting, App.WebAPI, App.Bootstrap и вот это вот все.
Для этого как раз и подходят всякие DDD, CQRS и т.д. Но опять же для этого архитектуру не переделывать нужно, а буквально пилить с нуля под такой функционал.
Хотя по сути на бэке всегда проще перекрыть интерфейс. Нет входящих данных - нет работы. Ну и тупо хостед-сервисы на паузу ставить.
Не просто использовал а-ля "T Sum<T>(T[] array)", а для чего-нибудь более серьёзного: статические свойства имплементации интерфейса, переиспользование кода, оптимизации и т.д.
Например, как в дотнете в TensorPrimitives, где они используют один метод для множества операций, а операции реализуются через структуры:
https://source.dot.net/#System.Numerics.Tensors/System/Numerics/Tensors/netcore/TensorPrimitives.Abs.cs,d460a0e95bc8bd56
А то во многих выступлениях/презентациях/блогах по C# 11 упоминали какую-то мелкую хуйню, ну максимум упоминали generic math и этот "T Sum<T>(T[] array)".
Использовал, когда на одном проекте надо было эндпоинты спрятать за фича-флагами.
Забыл что это добавили и сначала так горел, что надо ручками все это дело потом подрубать где надо.
Потом вспомнил и сильно кайфанул.
Ну, чтобы понятно было.
inteface IEndPoint<TRequest, TResponse>
{
Task<TResponse> Handle(TRequest request);
static abstract void ConfigEndpoint(IServiceCollection services);
static abstract void AddEnpoint(IWebApplication app, IConfiguration config);
}
И к этому делу - ConfigEndpointsFromAssembly(Assembly), AddEndpointsFromAssembly(Assembly)
В общем вышло оч аккуратненько и удобно. Так что в принципе понравилось.
>>160335
Ниже я написал только про generic'и, а ведь эту фичу можно использовать и без generic'ов. По типу:
interface ICommand
{
static abstract string Description { get; }
}
или как в >>160287
Вот более простой пример:
IParsable<TSelf>
https://learn.microsoft.com/en-us/dotnet/api/system.iparsable-1?view=net-8.0
Позволяет написать generic метод парсинга: "T Parse<T>(string text) where T : IParsable<T>"
Что они в дотнете и сделали (пример посложнее), добавив доп. интерфейсы с некоторыми методами и свойствами:
https://source.dot.net/#System.Private.CoreLib/src/libraries/System.Private.CoreLib/src/System/Number.Parsing.cs
IBinaryIntegerParseAndFormatInfo<TSelf> и IBinaryFloatParseAndFormatInfo<TSelf> - для парсинга и форматирования.
IHexOrBinaryParser<TInteger> - используется в методе для парсинга из двоичного и шестнадцатеричного представления (для 10-тиричного представления там всё немного сложнее, поэтому там отдельный метод).
И вот один метод TryParseBinaryIntegerHexOrBinaryNumberStyle<TChar, TInteger, TParser>() который парсит из этих 2-х представлений. И он один может парсить разные типы целых чисел (все базовые integer типы: Int8, UInt64 и т.д.) благодаря всем этим интерфейсам и доп. типам (HexParser<TInteger>, BinaryParser<TInteger> и т.д.).
А вот почему ещё реализации IHexOrBinaryParser<TInteger> (HexParser<TInteger> и BinaryParser<TInteger>) являются структурами:
Все типы которые метод может парсить являются Value types, и в перечисленных методах и интерфейсах используются generic'и, а значит для метода TryParseBinaryIntegerHexOrBinaryNumberStyle<TChar, TInteger, TParser>() JIT сгенерирует отдельный оптимизированный (это важно) код для каждой комбинации generic аргументов и заинлайнит все нужные методы у этих generic'ов. Благодаря этому этот один(!) метод также эффективен, как если бы они написали метод для каждого целого типа отдельно (10 * 2 = 20 методов - 10 типов и 2 формата (двоичный и шестнадцатеричный)). В итоге: лучше поддерживаемость кода (нет кучи методов с почти одинаковым кодом), производительность (как если бы написать методы под каждый тип).
Вообще, когда первый раз такое видишь очень тяжело понять что происходит и зачем такие сложности.
Поэтому пример с TensorPrimitives лучше всех, потому что чтобы им добавить новую операцию нужно написать совсем немного кода который описывает саму операцию, а не целый метод, который нужно оптимизировать, векторизироввть и т.д. Вот чтобы добавить побитовой And: https://source.dot.net/#System.Numerics.Tensors/System/Numerics/Tensors/netcore/TensorPrimitives.BitwiseAnd.cs
Так что теперь generic'и решают проблему дублирования кода ещё лучше.
>>160335
Ниже я написал только про generic'и, а ведь эту фичу можно использовать и без generic'ов. По типу:
interface ICommand
{
static abstract string Description { get; }
}
или как в >>160287
Вот более простой пример:
IParsable<TSelf>
https://learn.microsoft.com/en-us/dotnet/api/system.iparsable-1?view=net-8.0
Позволяет написать generic метод парсинга: "T Parse<T>(string text) where T : IParsable<T>"
Что они в дотнете и сделали (пример посложнее), добавив доп. интерфейсы с некоторыми методами и свойствами:
https://source.dot.net/#System.Private.CoreLib/src/libraries/System.Private.CoreLib/src/System/Number.Parsing.cs
IBinaryIntegerParseAndFormatInfo<TSelf> и IBinaryFloatParseAndFormatInfo<TSelf> - для парсинга и форматирования.
IHexOrBinaryParser<TInteger> - используется в методе для парсинга из двоичного и шестнадцатеричного представления (для 10-тиричного представления там всё немного сложнее, поэтому там отдельный метод).
И вот один метод TryParseBinaryIntegerHexOrBinaryNumberStyle<TChar, TInteger, TParser>() который парсит из этих 2-х представлений. И он один может парсить разные типы целых чисел (все базовые integer типы: Int8, UInt64 и т.д.) благодаря всем этим интерфейсам и доп. типам (HexParser<TInteger>, BinaryParser<TInteger> и т.д.).
А вот почему ещё реализации IHexOrBinaryParser<TInteger> (HexParser<TInteger> и BinaryParser<TInteger>) являются структурами:
Все типы которые метод может парсить являются Value types, и в перечисленных методах и интерфейсах используются generic'и, а значит для метода TryParseBinaryIntegerHexOrBinaryNumberStyle<TChar, TInteger, TParser>() JIT сгенерирует отдельный оптимизированный (это важно) код для каждой комбинации generic аргументов и заинлайнит все нужные методы у этих generic'ов. Благодаря этому этот один(!) метод также эффективен, как если бы они написали метод для каждого целого типа отдельно (10 * 2 = 20 методов - 10 типов и 2 формата (двоичный и шестнадцатеричный)). В итоге: лучше поддерживаемость кода (нет кучи методов с почти одинаковым кодом), производительность (как если бы написать методы под каждый тип).
Вообще, когда первый раз такое видишь очень тяжело понять что происходит и зачем такие сложности.
Поэтому пример с TensorPrimitives лучше всех, потому что чтобы им добавить новую операцию нужно написать совсем немного кода который описывает саму операцию, а не целый метод, который нужно оптимизировать, векторизироввть и т.д. Вот чтобы добавить побитовой And: https://source.dot.net/#System.Numerics.Tensors/System/Numerics/Tensors/netcore/TensorPrimitives.BitwiseAnd.cs
Так что теперь generic'и решают проблему дублирования кода ещё лучше.
ох если бы еще дженерик методы были так же эффективны в своем вызове....
какая же конченная капча просто пи....
>ох если бы еще дженерик методы были так же эффективны в своем вызове....
Эффективны? В смысле производительность? Можешь пояснить чуть более подробно, что ты имеешь ввиду?
Если про производительность, то только виртуальные generic методы ужасно медленные:
https://devblogs.microsoft.com/dotnet/performance_improvements_in_net_7/#jit-helpers
>you may have heard the refrain that generic virtual methods are relatively expensive. They are, comparatively.
>GenericNonVirtual 0.4866 ns
>GenericVirtual 6.4552 ns
щас уже не найду но была статья на хабре где рассматривался один случай что дженерик начинал работать медленнее стоило добавить в класс еще один пустой метод который и не вызывали вовсе. Что то там из за размера кеша методов. не помню. Про виртуальность или нет - тоже не помню.
Приходит муж с работы, а жена ему сообщает новость:
- Ты только представь, наш сосед Иванов выиграл в лотерею ВОЛГУ!!!!
Муж говорит:
- НЕ ВЕРЮ!!!
Жена?
- Ну пойди проверь!
Муж уходит.... Возвращается через полчаса и говорит:
- Не Иванов, а Рабинович, не в лотерею, а в преферанс, не Волгу, а три
рубля, не выиграл, а проиграл.
И тем не менее. Я не припомню чтобы там речь шла про виртуальные дженерик методы. Это вообще редкость - виртуальные методы такого рода в силу малой нужности.
А в шарпе этого хватает - вон Method Group и лямбда, казалось бы ну в чем разница, а бенчмарк вам растолкует. Я давно не следил за темой, но разве пофиксили?
не говоря уже про new T(), который под капотом - УНЫЛОЕ Activator.CreateInstance[T].
Кто-то соптимизировал это наконец? Ответ знаете сами. Сколько десятков тысяч лет ждать фикса?
ну вообще то ты прав. В преферанс
это было на ютубе.
https://www.youtube.com/watch?v=9OjWL4gP1Jo
и вот сам ишью
https://github.com/dotnet/runtime/issues/3877
никакой виртуальности там нет.
да. поэтому и 3 рубля. Я ж не слон все помнить. Но саму суть это не меняет - у дженериков есть траблы которые влияют на перфоманс и мне по душе когда это фиксят разрабы CLR, а не всякие хаки дрюки.
Я верю, ибо кодовая база райнтайма (особенно C++ часть) это сплошная каша, в которой куски времён .NET Framework'а (хоть их и уже практически нет), просто старый код или старые реализации для которых уже давно существуют современные альтернативы, и т.д. Там даже в большинстве своём C++ 03.Так что я не удивляюсь багам/странностям рантайма и JIT'а. Ну хоть NativeAOT они писали "по-современному" (очень много рантаймового кода на C#, C++ код по-новее и т.д.), вон даже exception handling они портировали из NativeAOT в CoreCLR:
https://github.com/dotnet/runtime/pull/88034
>>162263
>никакой виртуальности там нет.
Как я понял это был баг
Вон у них сколько висел другой баг (и то они пофиксили только частично):
https://github.com/dotnet/runtime/issues/6924
>Unused generic type parameter should not cause loader failure
>Nov 2, 2016
>>162242
>не говоря уже про new T(), который под капотом - УНЫЛОЕ Activator.CreateInstance[T].
Generic math частично заменяет это и теперь можно писать что-то типа T.Create(...) с соответствующими интерфейсами которые T реализует (что конечно не всегда возможно).
>Как я понял это был баг
Баг. Но фикс лишь исправил иерархический поиск на "ищи сразу в глобальном кеше методов, что не самый оптимальный путь и хак "добавь пустые методы" не потерял актуальности.
>(что конечно не всегда возможно).
именно. конструкторы есть у всех, а эти интерфейсы не у многих. Поэтому добавление такого констрейна у дженерика попросту невозможно.
Им что жалко сгенерить какое нибудь подобие экспрешена раз уж CLR не может в нужное? Вижу что жалко.
>Им что жалко сгенерить какое нибудь подобие экспрешена раз уж CLR не может в нужное? Вижу что жалко.
Видимо не в приоритете. Особенно после того как они добавили generic math.
и то верно. у шарписта лоб большой - он запомнит все эти подводные камни. это ж вам не пхп где...ой.
Щас не знаю, а вот помню менял енумы (интовые) на прямые инты - скорость была х4. Спрашивается, ну как так то. Ответ - а вот так вот.
>и то верно. у шарписта лоб большой - он запомнит все эти подводные камни. это ж вам не пхп где...ой.
Вообще они считают, что простой шарпист не должен упарываться во все эти мелочи (они и у себя некоторые ручные микро оптимизации отсекают с мыслью "этим должен заниматься JIT" (и потом улучают это в JITе только лет через 5)).
>Щас не знаю, а вот помню менял енумы (интовые) на прямые инты - скорость была х4. Спрашивается, ну как так то. Ответ - а вот так вот.
А вот тут хотелось бы поподробней.
>Просто заменил switch case с enum на просто числа.
JIT походу (как всегда) обосрался, хотя разницы в кодегене не должно быть.
Капча с таймаутами..., как троллинг какой-то...
А ты любишь чтобы тебя ругали? Мазохист?
А вообще гугли ковариантность и контрвариантность
А к ним еще in/out в описаниях типов
Смотря что ты делаешь. Если возвращаемый тип наследует или реализует интерфейс нижележащего метода то схуя бы ему ругаться?
Да я менял вообще на рандомный тип и не ругалась. Например реализовал интерфейс IClonable для собственного
класса с методом
public virtual object Clone()
а в наследнике переопределял
public override string Clone()
И студия даже не задала вопросов
>>162955
Чтобы понимать, что я делаю не так. Если я заменю тип в параметре переопределяемого метода, то студия ругается, а здесь почему-то нет.
А string это по твоему не object?
И почему ты постоянно говоришь про студию если у тебя тупые вопросы к компилятору?
ааа, вот он че. Вот я дебил.
Deep .NET
https://www.youtube.com/playlist?list=PLdo4fOcmZ0oX8eqDkSw4hH9cSehrGgdr1
>Writing async/await from scratch in C# with Stephen Toub
>Deep Dive on LINQ with Stephen Toub
>An even DEEPER Dive into LINQ with Stephen Toub
>Deep Dive into RegEx with Stephen Toub
>A Complete .NET Developer's Guide to Span with Stephen Toub
И почему они раньше не запилили это?
Майки контент подвезли...
Выглядит интересно, но в том виде в котором показано на видео пиздец как сомниительно. Функционально ннчего не добавляет, но вносит кучу путаницы между реальными свойствами и новыми расширениями, которые под них маскируются, но по сути остаются обычными методами. А так же между наследованием и explicit расширениями. Я уже прямо предчувствую пучок вопросов для джунов на собесах, аналогичным тем как ведут себя конструкторы и переопределения, при наследовании А от Б от С и т.д. Только тут нужно будет запоминать кучу особенностей поведения для цепочек расширений.
Ну и опять же нужна будет нормальная поддержка в IDE, чтобы со всей этой кашей работать. Как минимум выделять всё это в отдельную категорию, чтобы можно нормально было все это отслеживать.
Ладно, мне все равно еще как минимум год с .net6 только работать, так что когда я с этим столкнусь, оно надеюсь будет уже допилено до вменяемого состояния.
Вот раньше было Array.Length и Array.Count()
И как бы сразу понятно, что предпочтительнее. А теперь любую залупу будут пихать в свойство — просто потому, что лень писать скобочки.
Ага, а еще обязательно какая-нибудь залупа с сериализацией/десереализацией вылезет.
Свойства без хранения самого свойства или без переопределения существующих выглядит как ерунда. Лучше бы сделали прикрепляемые свойства для обычных классов, раз уж на то пошло.
var t1 = test.Count;
var t2 = test.Count();
В чем разница? Что юзать то нужно?
![2024-05-2311-23-47.png](https://2ch.life/pr/thumb/3097760/17164547046410s.jpg)
>Нажми ф12 на каждом и посмотри
Майкрософт скрыла свой код, там разве что можно посмотреть сигнатуру.
Лучше использовать https://source.dot.net/ и забивать в поиск искомый класс. Вроде есть расширения для студии, которые по сути при нажатии F12 автоматом перекидывают на страницу source.dot.net, но мне показалось это неудобным калом т.к. перебивает работу F12 в других случаях.
>>166246
Count() это метод расширения для Enumerable — базового класса List. Задача которого быть универсальным для большинства коллекций. В качестве параметра, этот метод принимает объект, реализующий интерфейс IEnumerable, поэтому метод вообще не вдупляет какой реальный тип у коллекции, а ведь у каждого типа свои методы получения количества итемов. К примеру у списка за это отвечает свойство Count, а у массива — свойство Length. У некоторых вообще нет ничего подобного, поэтому приходится вычислять count методом перебора итемов энумератора.
Короче, внутри test.Count() все сводится к первому варианту test.Count + проверки на тип и выбор самого оптимального варианта. И самое главное, свойства Count и Length уже хранят готовые значения, в то время как метод Count() будет выполнять проверки каждый раз, когда ты этот метод запускаешь.
Поэтому вариант с расширением используют для чего-то универсального, для чего можно пожертвовать производительностью, хотя и это можно свести к минимуму, если понимать как работает Count() — просто не пихать его, например, в циклы, а заранее вывести результат в переменную.
Но если у тебя есть доступ к конкретному свойству конкретного типа, то лучше использовать это свойство. И самому надо стараться делать свойства с таким же подходом и не пихать в них громадную логику.
Поэтому ты наверно понял, какую свинью могут подложить разработчики с новыми расширениями, маскируя метод под свойство. И ведь кто-то возьмет и напишет это
>for (int i = 0; i < n.Count; i++) { }
А внутри будет запрятан метод Count() который каждый раз перебирает коллекцию. И этот перебор будет происходить при каждой итерации цикла.
![2024-05-2311-23-47.png](https://2ch.life/pr/thumb/3097760/17164547046410s.jpg)
>Нажми ф12 на каждом и посмотри
Майкрософт скрыла свой код, там разве что можно посмотреть сигнатуру.
Лучше использовать https://source.dot.net/ и забивать в поиск искомый класс. Вроде есть расширения для студии, которые по сути при нажатии F12 автоматом перекидывают на страницу source.dot.net, но мне показалось это неудобным калом т.к. перебивает работу F12 в других случаях.
>>166246
Count() это метод расширения для Enumerable — базового класса List. Задача которого быть универсальным для большинства коллекций. В качестве параметра, этот метод принимает объект, реализующий интерфейс IEnumerable, поэтому метод вообще не вдупляет какой реальный тип у коллекции, а ведь у каждого типа свои методы получения количества итемов. К примеру у списка за это отвечает свойство Count, а у массива — свойство Length. У некоторых вообще нет ничего подобного, поэтому приходится вычислять count методом перебора итемов энумератора.
Короче, внутри test.Count() все сводится к первому варианту test.Count + проверки на тип и выбор самого оптимального варианта. И самое главное, свойства Count и Length уже хранят готовые значения, в то время как метод Count() будет выполнять проверки каждый раз, когда ты этот метод запускаешь.
Поэтому вариант с расширением используют для чего-то универсального, для чего можно пожертвовать производительностью, хотя и это можно свести к минимуму, если понимать как работает Count() — просто не пихать его, например, в циклы, а заранее вывести результат в переменную.
Но если у тебя есть доступ к конкретному свойству конкретного типа, то лучше использовать это свойство. И самому надо стараться делать свойства с таким же подходом и не пихать в них громадную логику.
Поэтому ты наверно понял, какую свинью могут подложить разработчики с новыми расширениями, маскируя метод под свойство. И ведь кто-то возьмет и напишет это
>for (int i = 0; i < n.Count; i++) { }
А внутри будет запрятан метод Count() который каждый раз перебирает коллекцию. И этот перебор будет происходить при каждой итерации цикла.
1. В студии работает сорслинк, но может быть выключен. Все майковские пакеты с ним собраны
2. С решарпером по ф12 отрабатывает нормальный декомпилятор, а не стандартный обрубок
С решарпером все понятно, а как первое поможет?
Потому что все рекомендации, которые я видел, типа "Enable navigation to Source Link and Embedded Sources", не распространяются на исходники от майкрософт. В итоге все сводилось к рекомендации установить расширение Ref12 (если не брать в расчет решарпер).
Может тогда не жевать кактус а поставить решарпер или идешку сменить?
Только не нужно про платность загонять. Есть варианты от "мой хозяин на работе даёт альтимейт лицуху" до "пиратских серверов активации по аналогии kms"
>мой хозяин на работе даёт альтимейт лицуху
Мне на одной из работ поставили энтерпрайз версию студии, так в ней часть 'бесплатных' расширений отвалилась. Т.к. типа если ты на комьюнити версии, то можно пользоваться бесплатно, а если у тебя оплачена лицензия, значит бабки есть, плати и за расширения тоже.
В общем. С недавних пор какого-то фига в студии бесконечно растет потребление памяти.
Просто, буквально. Я открываю солюшин. Минут 10 все вроде ок. Но потом я открываю диспечер задач, вижу, что студия жрет 28 гигов из моих 32. И это выглядит как: растет до состояния, что студия перестает как-то на меня реагировать, потом - хренак, падает до 1,4, и потом вот такими циклами происходит.
Че эт может быть? У меня из расширений - буквально нифига нет. Всякие штуки пробовал поотключать. но нифига не помогло.
Сейчас из-за всей этой хурмы пересел на VSCode. Жить можно, но блин, я как-бы привык уже к студии. Переставлять боюсь из-за того что настроечки же свои наделал, чтобы максимально удобно, окошки там попрятал лишние, ненужные кнопки убрать, снова этим заниматься не хочется особо.
Настройки импортируй...
Почему у дотнета сообщество как в 1С? Его как бы нет.
Вроде всё не так плохо, не?
>>162298
>Им что жалко сгенерить какое нибудь подобие экспрешена раз уж CLR не может в нужное? Вижу что жалко.
Как я понял, они кешируют нужную инфу. А вызывают конструктор через кешированный указатель на метод.
https://source.dot.net/#System.Private.CoreLib/src/System/RuntimeType.CoreCLR.cs,d90ca8e3a15370ca
![image.png](https://2ch.life/pr/thumb/3097760/17165278764020s.jpg)
Обычная запись юникода через escape последовательности.
Здесь так не шутят.
Че делать?
Нашел
https://learn.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-13
Но ещё есть:
https://github.com/dotnet/roslyn/blob/main/docs/Language%20Feature%20Status.md
>Ref/unsafe in iterators/async
Такую мелочь фиксить так долго...
>Ref Struct Interfaces
Байтоёбы стали счастливее
https://github.com/dotnet/runtime/issues/102671
>[API Proposal]: Employ allows ref struct in libraries
А что вы думаете по поводу C# 13? (discriminated union дебилы сразу идут нахуй)
А что тут думать. Тред на гитхабе "сделайте блин ConfigureAwait настройку на уровне проекта/солюшена/вселенной" так и будет висеть вечность. А делают то, что нужно мало кому (ну мне в принципе нужно, но как то живу и без этого, а ConfigureAwait заипал.
И кто то из этих "много" кинул пр с реализацией фичи?
Хочешь что то сделать хорошо - сделай это сам, а не ной как баба
Ты дурачок какой-то.
Неужели это настолько невостребованный фреймворк?
Настолько невостребованный Udemy.
Потому что шарп обновляется так быстро, что даже на английском языке иногда нет актуальной литературы и курсов.
По моему сейчас уже даже известные авторы забили на обновление текущих и написание новых книг. Потому что прохождение полного издательского цикла от написания до печати книги займет столько времени, что успеет пара новых версий .net-а выйти.
https://github.com/dotnet/csharplang/discussions/2073
Люблю обмазываться менеджерами и другой подобной хренью...
Use internal Luke
Мне кажется, но все случаи, когда тебе нужны дружественные классы, легко разрулить модификаторами доступа, благо в шарпе есть internal и protected internal. Если прям трясешься от того, что из других классов сборки можно будет щупать другие методы, то просто выдели для таких классов отдельный проект.
Звучит как желание иметь еще один слой зависимостей, от которых заебешься, когда будешь разгребать чужой говнокод. Не нужно.
Да все удастся. можно вообще паблик сделать и тоже будет работать. Но те же понимаешь почему в природе существует не только паблик (хотя все при нем удается)?
Ты конкретный кейс давай, когда friend-класс принесет значимые профиты, попутно не сделав код сильносвязанным говном. И пояснение за одно, почему в данном кейсе использование того же internal будет моветоном.
ну там выше гитхаб дали -там тебе доводы.
ты понимаеш что френды и интерналы это разные вещи по уровню доступа и по уровню контроля открываемости?
Не увиливай. Давай таой пример, когда оно тебе нужно в шарповом коде.
Как по мне, это плюсовая говнофича, которая делает код излишне связным и сложным в поддерже. И как бы то, что разрабы других языков и в том числе Шарпа не стремятся ее из плюсов в свои языки переносить как раз хороший аргумент в сторону ее ненужности в исходном виде.
Как по мне, это костыль языка, в котором до последнего времени не было нормальной модульности кода (в последних стандартах, слышал, что что-то для этого завезли), и в котором для того, чтобы использовать класс, лежащий рядом в проекте, нужно блядь по сути вставлять исходник с объявлением этого класса в свой исходник.
В какой-то степени friend это костыль, как список исключений к правилу. Т.е., вот у нас есть инкапсуляция и т.д., а вот у нас есть список на кого эта инкапсуляция не распространяется, т.е. исключение из правила, а это хоть где нибудь, но будет создавать геморрой. Вот даже если добавить аттрибут по типу InternalsVisibleTo(Type[] types), и он никак не будет проявлять себя на уровне рефлексии, например, будет чем-то вроде хака в компиляторе, то тулзы всё равно должны будут его понимать (компилятор, анализаторы, Intellisense и т.д.). И вот в проверку видимости члена добавятся ещё исключения, но теперь более конкретные (если InternalsVisibleTo, на уровне сборки, уже был, то теперь появится конкретный список типов).
Ну хоть и сама фича относительно маленькая, но небольшие неудобности в реализации имеет и добавляет ещё материала при изучении языка.
Ну а плюс: friend сохраняет инкапсуляцию типов (в некоторых местах можно будет им заменить internal и не светить внутренностями на всю сборку).
>>170196
Так, блядь, friend это не про абстракцию (в основном), а, например, когда у тебя есть Foo и FooManager, и Foo не полностью самостоятельный объект и бесполезен без FooManagerа (FooManager их создаёт, владеет ими, удаляет их и дополняет их функционал).
>Как по мне, это костыль языка, в котором до последнего времени не было нормальной модульности кода (в последних стандартах, слышал, что что-то для этого завезли), и в котором для того, чтобы использовать класс, лежащий рядом в проекте, нужно блядь по сути вставлять исходник с объявлением этого класса в свой исходник.
Это всё не имеет отношение к friend. friend существует, чтобы выборочно нарушить инкапсуляцию своих членов (ну в C++ там всё немного серьёзнее).
>И как бы то, что разрабы других языков и в том числе Шарпа не стремятся ее из плюсов в свои языки переносить как раз хороший аргумент в сторону ее ненужности в исходном виде.
Ну а я бы сказал что большинство ООП языков, имеют это ООП в немного кастрированном виде, а потом со временем начинают придумывать различные костыли.
В какой-то степени friend это костыль, как список исключений к правилу. Т.е., вот у нас есть инкапсуляция и т.д., а вот у нас есть список на кого эта инкапсуляция не распространяется, т.е. исключение из правила, а это хоть где нибудь, но будет создавать геморрой. Вот даже если добавить аттрибут по типу InternalsVisibleTo(Type[] types), и он никак не будет проявлять себя на уровне рефлексии, например, будет чем-то вроде хака в компиляторе, то тулзы всё равно должны будут его понимать (компилятор, анализаторы, Intellisense и т.д.). И вот в проверку видимости члена добавятся ещё исключения, но теперь более конкретные (если InternalsVisibleTo, на уровне сборки, уже был, то теперь появится конкретный список типов).
Ну хоть и сама фича относительно маленькая, но небольшие неудобности в реализации имеет и добавляет ещё материала при изучении языка.
Ну а плюс: friend сохраняет инкапсуляцию типов (в некоторых местах можно будет им заменить internal и не светить внутренностями на всю сборку).
>>170196
Так, блядь, friend это не про абстракцию (в основном), а, например, когда у тебя есть Foo и FooManager, и Foo не полностью самостоятельный объект и бесполезен без FooManagerа (FooManager их создаёт, владеет ими, удаляет их и дополняет их функционал).
>Как по мне, это костыль языка, в котором до последнего времени не было нормальной модульности кода (в последних стандартах, слышал, что что-то для этого завезли), и в котором для того, чтобы использовать класс, лежащий рядом в проекте, нужно блядь по сути вставлять исходник с объявлением этого класса в свой исходник.
Это всё не имеет отношение к friend. friend существует, чтобы выборочно нарушить инкапсуляцию своих членов (ну в C++ там всё немного серьёзнее).
>И как бы то, что разрабы других языков и в том числе Шарпа не стремятся ее из плюсов в свои языки переносить как раз хороший аргумент в сторону ее ненужности в исходном виде.
Ну а я бы сказал что большинство ООП языков, имеют это ООП в немного кастрированном виде, а потом со временем начинают придумывать различные костыли.
>> Так, блядь, friend это не про абстракцию (в основном), а, например, когда у тебя есть Foo и FooManager, и Foo не полностью самостоятельный объект и бесполезен без FooManagerа (FooManager их создаёт, владеет ими, удаляет их и дополняет их функционал).
Решается либо вложенными классами, либо internal. Боишься, что internal-члены Foo будет трогать кто-то кроме FooManager - выделяешь для них публичный интерфейс, а саму реализацию выносишь в отдельную сборку. Либо добавляешь свой атрибут и один раз пишешь свой roslyn-анализатор, который будет это проверять. Все современные ide-ки (студия, Rider) умеют с ними работать и будут подсвечивать ошибку как в коде, при редактировании. Во время компиляции он тоже будет выдавать предупреждение. Можно настроить проект так, чтобы он считалось ошибкой и обрывало сборку. Потом этот анализатор можно будет запаковать в nuget и подключать к другим своим проектам. Пишутся они не сильно сложно.
https://habr.com/ru/articles/455844/
>> Это всё не имеет отношение к friend. friend существует, чтобы выборочно нарушить инкапсуляцию своих членов
Разрабы Шарпа и других языков вполне понимали необходимость иногда нарушать инкапсуляцию. Они и дали тебе инструменты, которых в плюсах нет, в силу их исторического наследия. Эти инструменты - вложенные классы и модули+internal. Просто при объявления класса френдом, ты даёшь ему доступ ко ВСЕМ private-методам класса. Потом это принесёт много страданий, так как хуй поймешь что от чего зависит, особенно если классы-друзья достаточно большие и имеют большую историю доработок разными разрабами, так как контрактом их взаимодействия по сути являются все члены класса, и их изменение может неожиданным образом зааффектить поведение класса-друга. internal-методы это же как раз возможность задать на такой случай дополнительный уровень контрактов.
>> Ну а я бы сказал что большинство ООП языков, имеют это ООП в немного кастрированном виде, а потом со временем начинают придумывать различные костыли.
Ну так friend это тоже костыль. И он никому из создателей более современных языков по душе не пришёлся.
>> Так, блядь, friend это не про абстракцию (в основном), а, например, когда у тебя есть Foo и FooManager, и Foo не полностью самостоятельный объект и бесполезен без FooManagerа (FooManager их создаёт, владеет ими, удаляет их и дополняет их функционал).
Решается либо вложенными классами, либо internal. Боишься, что internal-члены Foo будет трогать кто-то кроме FooManager - выделяешь для них публичный интерфейс, а саму реализацию выносишь в отдельную сборку. Либо добавляешь свой атрибут и один раз пишешь свой roslyn-анализатор, который будет это проверять. Все современные ide-ки (студия, Rider) умеют с ними работать и будут подсвечивать ошибку как в коде, при редактировании. Во время компиляции он тоже будет выдавать предупреждение. Можно настроить проект так, чтобы он считалось ошибкой и обрывало сборку. Потом этот анализатор можно будет запаковать в nuget и подключать к другим своим проектам. Пишутся они не сильно сложно.
https://habr.com/ru/articles/455844/
>> Это всё не имеет отношение к friend. friend существует, чтобы выборочно нарушить инкапсуляцию своих членов
Разрабы Шарпа и других языков вполне понимали необходимость иногда нарушать инкапсуляцию. Они и дали тебе инструменты, которых в плюсах нет, в силу их исторического наследия. Эти инструменты - вложенные классы и модули+internal. Просто при объявления класса френдом, ты даёшь ему доступ ко ВСЕМ private-методам класса. Потом это принесёт много страданий, так как хуй поймешь что от чего зависит, особенно если классы-друзья достаточно большие и имеют большую историю доработок разными разрабами, так как контрактом их взаимодействия по сути являются все члены класса, и их изменение может неожиданным образом зааффектить поведение класса-друга. internal-методы это же как раз возможность задать на такой случай дополнительный уровень контрактов.
>> Ну а я бы сказал что большинство ООП языков, имеют это ООП в немного кастрированном виде, а потом со временем начинают придумывать различные костыли.
Ну так friend это тоже костыль. И он никому из создателей более современных языков по душе не пришёлся.
>Решается либо вложенными классами
Foo.FooManager это странно, а что делать когда есть Foo1, Foo2 и FooManager.
>выделяешь для них публичный интерфейс,
А что делать в случаях FooManager.DoSomething(IFoo[] foos)?
>а саму реализацию выносишь в отдельную сборку
Не всегда возможно. И к тому же, что, выносить все такие типы? всё дробить на сборки?
>roslyn-анализатор
Я не упомянул, но смотрел различные варианты: от EditorBrowsable(EditorBrowsableState.Never) до анализаторов. Думал про source генераторы, если бы можно было бы обращаться к членам, которые ещё только будут сгенерированы source генератором, то генератор, например, бы просто заменял такие обращение на методы с UnsafeAccessorAttribute. Такое решение было бы идеально (как friend классы, весь класс пишется как обычно). Текущие рещения с анализаторами и генераторами - решения с разной степенью костыльности (как и сам friend).
Все эти решения мне не нравятся, потому что они побольшому счёту workaroundы. Но решение с интерфесом самое адекватное из этих вариантов. Только вот городить интерфейс даже когда это менеждер с его "детьми" является сам internal, т.е. чисто для внутренней реализации, делать всё public/internal?
Тут нужно уточнить, что я в принципе против делать всё члены internal для типа, даже если он internal для сборки. Ну может я не понимаю, как работает инкапсуляция, и что делать всё внутренние типы и члены internal это норма.
>Просто при объявления класса френдом, ты даёшь ему доступ ко ВСЕМ private-методам класса.
Ну тут выбор: либо internal - видно только то что нужно, но всем в сборке, либо friend - видно всё, но только нужным классам.
>Потом это принесёт много страданий, так как хуй поймешь что от чего зависит, особенно если классы-друзья достаточно большие и имеют большую историю доработок разными разрабами, так как контрактом их взаимодействия по сути являются все члены класса, и их изменение может неожиданным образом зааффектить поведение класса-друга.
Тут согласен, но я не считаю это настолько большой проблемой.
>Они и дали тебе инструменты, которых в плюсах нет, в силу их исторического наследия.
Ну тут я согласен, что у C++ большое легаси и у разных языков, разные аудитории и разные общепринятые подходы.
Были ещё предложения с internal, но в пределах неймспейса (что тоже было бы неплохо или даже лучше).
>Решается либо вложенными классами
Foo.FooManager это странно, а что делать когда есть Foo1, Foo2 и FooManager.
>выделяешь для них публичный интерфейс,
А что делать в случаях FooManager.DoSomething(IFoo[] foos)?
>а саму реализацию выносишь в отдельную сборку
Не всегда возможно. И к тому же, что, выносить все такие типы? всё дробить на сборки?
>roslyn-анализатор
Я не упомянул, но смотрел различные варианты: от EditorBrowsable(EditorBrowsableState.Never) до анализаторов. Думал про source генераторы, если бы можно было бы обращаться к членам, которые ещё только будут сгенерированы source генератором, то генератор, например, бы просто заменял такие обращение на методы с UnsafeAccessorAttribute. Такое решение было бы идеально (как friend классы, весь класс пишется как обычно). Текущие рещения с анализаторами и генераторами - решения с разной степенью костыльности (как и сам friend).
Все эти решения мне не нравятся, потому что они побольшому счёту workaroundы. Но решение с интерфесом самое адекватное из этих вариантов. Только вот городить интерфейс даже когда это менеждер с его "детьми" является сам internal, т.е. чисто для внутренней реализации, делать всё public/internal?
Тут нужно уточнить, что я в принципе против делать всё члены internal для типа, даже если он internal для сборки. Ну может я не понимаю, как работает инкапсуляция, и что делать всё внутренние типы и члены internal это норма.
>Просто при объявления класса френдом, ты даёшь ему доступ ко ВСЕМ private-методам класса.
Ну тут выбор: либо internal - видно только то что нужно, но всем в сборке, либо friend - видно всё, но только нужным классам.
>Потом это принесёт много страданий, так как хуй поймешь что от чего зависит, особенно если классы-друзья достаточно большие и имеют большую историю доработок разными разрабами, так как контрактом их взаимодействия по сути являются все члены класса, и их изменение может неожиданным образом зааффектить поведение класса-друга.
Тут согласен, но я не считаю это настолько большой проблемой.
>Они и дали тебе инструменты, которых в плюсах нет, в силу их исторического наследия.
Ну тут я согласен, что у C++ большое легаси и у разных языков, разные аудитории и разные общепринятые подходы.
Были ещё предложения с internal, но в пределах неймспейса (что тоже было бы неплохо или даже лучше).
>И он никому из создателей более современных языков по душе не пришёлся.
А чем covariant return, не пришёлся по душе разрабам шарпа, что он появился только в C# 9 (.NET 5, 2020 год) (и это ещё с учётом того, что касты, что в mono, что CoreCLR, что в NativeAOT - no-op, если убрать проверки). И это ещё к моему тейку, про языки ООП-кастраты.
Ну и как аргумент это не очень (там вроде разрабы шарпа примерно так же говорили). К тому же у нас есть GC язык с hardware intrinsicами, арифметикой управляемых указателей, подержка простых указателей (в т.ч. указателей на функции), вся каша с ref (и она становится только больше) и т.д. Много таких языков? Т.е. одна часть языка - модная, современная, для полудомохозяек, а другая - high performance. Даже scoped ref добавили и всё ещё собиратся добавить больше: https://github.com/dotnet/csharplang/blob/main/proposals/expand-ref.md
Ну, а вообще ты прав.
Friend не даёт ничего принципиально нового, что нельзя сделать сейчас (и это ещё один минус для новой фичи), просто мне хочется видеть развитие и улучшение ООП (хоть я и понимаю его минусы), а не добавление новых парадигм и полуготовые фичи которые доделывают через пару лет (in, primary contructors, collections expressions и т.д.).
И да, половина моих тейков это ИМХО и ранняя стадия C++а головного мозга. К тому же я слишком тупой, чтобы нормально задефать свое мнение. Пусть хоть местные аноны что-нибудь напишут, а то >>167332 1С тред поживее будет.
>Ну тут выбор: либо internal - видно только то что нужно, но всем в сборке, либо friend - видно всё, но только нужным классам.
так то кул было бы иметь возможность приватное на уровне неймспейса, но у нас же шарп - тут много чего нет.
Я заметил, что для метода словаря Dictionary.TryGetValue даже несмотря на возвращение nullable-объекта, компилятор не требует проверки. Посмотрел в исходниках (пикрил 1), и там на выходном параметре стоит аргумент [MaybeNullWhen(false)]
Пытался повторить (пикрил 2). Создал тестовый класс, добавил собственный метод TryGetValue, который имитирует аналогичный метод в словаре.
Далее сделал метод TestMyFunction(), в котором использую свой TryGetValue, и как видите, в строке
>var n = myClass.Name;
видно подчеркивание, которое сигнализирует о рекомендации проверки на null экземпляра myClass.
В качестве сравнения, сделал метод TestDictionary(), где все ровно тоже самое, но только для метода словаря Dictionary.TryGetValue(). И вот здесь никакого предупреждения нет. Почему?
Я пытался использовать другие аргументы, типа [NotNullWhen(true)] и все работает, но я хочу понять почему не работает вариант, который использовался в метода для словаря?
А, понял.
[MaybeNullWhen(false)] сообщает, что метод может вернуть ноль.
Поэтому в параметре возврата не указывается nullable-тип:
> out MyClass result
А [NotNullWhen(true)] сообщает, что nullable-объект в случае успеха гарантированно что-то возвращает, поэтому здесь наоборот указывается nullable-тип:
> out MyClass? result
Попробовал, но ссылка пропадает непредсказуемым образом.
очевидно когда не нужно мешать сборщику мусора ее собрать
Пропадает она когда не остается строгих ссылок и проснулся GC
Применений валом. Например в подписках. Вон в WPF активно используется. Нельзя же бегать разбираться (на самом деле можно и нужно, но есть нюанс) кто когда куда исчез, поэтому там weak подписки
Но вот я пытался там сохранить ссылку на метод. Когда сразу же хочу получить ссылку, то она возвращается. Но почему-то спустя непродолжительное время TryGetTarget возвращает false, при том что я совершенно точно уверен в существовании экземпляра класса, на метод которого была дана ссылка.
Кажется дело в ссылке на метод. Если эту ссылку предварительно сохранить в поле, и уже ссылку на поле передавать в WeakReference, то тогда TryGetTarget возвращает true.
Но как тогда работают подписки? Почему там можно передать напрямую ссылку на метод? Или это из-за того, что она передается внутри класса, где происходит подписка.
Короче непонятно поведение методов.
>уверен в существовании экземпляра класса
Экземпляр класса и ссылка на его метод - 2 разные сущности. Если никто, кроме weak, не удерживает ссылку на что либо, то GC конечно его скушает.
Подписки так и работают. Только ты не путай обычные подписки - они стронг и вообще представляют собой сахар шарпа, и weak у которых совсем другой и весьма тупой синтаксис, который по факту реализация на коленке.
Они не пытаются удержать ссылку от сбора GC. Они смотрят жив ли адресат, но не мешают его уничтожению.
Например, в MVVM фреймворках мессенджеры сделаны обычно weak потому что там нужно слать сообщения между вьюмоделями, а в них сложно отписываться - это обычно делается в Dispose, но сам Disposable паттерн слишком неудобен для этого поэтому мессенджер удерживает ссылку на адресата как weakref и не мешает его убить и тем самым избегает утечки памяти.
Этакий костыль для тех кто не умеет в лайфтаймы (но это уже оффтоп)
ссылка на метод === ссылка на делегат (который уже, в свою очередь, ссылается на метод и его владельца). и поскольку никто кроме weak не удерживает ссылку на этот делегат, то делегат убивается GC
Еще кстати есть типа словаря с weak ключами - ConditionalWeakTable
>и поскольку никто кроме weak не удерживает ссылку на этот делегат, то делегат убивается GC
ааа
>ConditionalWeakTable
про это я читал, да
К примеру, мне надо поднять окно на передний план экрана. Свойством это бессмысленно делать т.к. нет возможности и желания отслеживать состояние нахождения окна на переднем плане.
Я могу в модели создать событие. Представление получая дата контекст может на это событие подписаться. Но тогда подписка не дает представлению помереть в нужный момент. Может есть какие-то решения подобной проблемы? Не всегда удается решить задачу через свойства.
1 weak подписка на свойство или событие даст помереть виду
2 стронг подписка требует отписки. Но события анлоадед может не быть
- в случае виртуализации его нет. Попап не выгружает контент тоже.
- закрыл окно и не будет анлоадед
Поэтому я с лайфтаймами делаю лайфтайм контрола метожом который подписывется на анлоадед контрола и на зак эл закрытие окна
В случае виртуализации можно подписывать и отписывать в датакониекстчэнжед
Но ты юзай слабые подписки и не мучай жопу.
Визуал студио не ставится,визуал студио код тоже.,
Тут вопрос в том, а должно ли это что-то уметь компилировать код?
>Можно и без подсветки синтаксисов
Как раз таки текстовых редакторов с подсветкой синтаксиса хоть жопой жуй — тот же Notepad++ или Sublime Text (выглядит современнее). Но все они не умеют компилировать — в них можно только писать код.
Студия сама по себе тоже не умеет. Запускаешь dotnet watch в соседнем окне и пишешь
>древний некроноут из 2009-ого с виндоовс 7
Где вы такое говно откапываете? У меня даже планшет пятилетней давности смог потянуть вижуал студию (правда смог только запустить), не говоря уже о вижуал студио коде.
Ну да ладно. Если есть доступ к интернету, то можешь попробовать онлайн компиляторы, типа
https://sharplab.io/
Там вообще ничего устанавливать не нужно. Но вот если придется пользоваться кастомными библиотеками или нюгет пакетами, тогда будет проблема.
Но вот самое-самое начало для освоения синтаксиса и проч сойдет. Хоть на телефоне пиши код. В качестве бонуса отображает IL-код.
Но если я сделаю класс User, который сам себя в БД пишет, дает доступ из любого места программы ко всему списку юзеров, еще и может отрисовать окошко с редактированием пользователя - пиздец, блядь, БОЖЕСТВЕННЫЙ КЛАСС, УУУУ, SRP, Уууууу, Ууууу. Как же - все в одном месте? Как же удобство работы и вот это вот все?
Биндиться по имени контрола не вариант т.к. иконка статуса находится в жопе UI. Мне надо этот статус как-то пробрасывать через вью-модель.
Но тут возникает две проблемы:
1. Ни один из режимов привязки не работает с ридонли свойством контрола. Пикрил 1 - как выглядит свойство. Пикрил 2 - как я пытался забиндить. (регистрация ДП при помощи RegisterReadOnly тоже пробовал)
2. Даже если я решу первую проблему, свойство вьюмодели, в таком случае должно иметь доступ и на чтение и не запись, но это дает возможность другим элементам попытаться изменить данное свойство, что нехорошо.
>Как же удобство работы и вот это вот все?
Удобство ведь только в теории, но на практике может прострелить колено.
Я встречался с ситуациями, когда самодеятельность суб-элементов приводила к тому, что они гадили в те моменты, когда их никто не просил. В итоге начинаются усложнения с запрещением этой самой самодеятельности.
Твой элемент будет шатать БД в не самое удачное время, потому что он не в курсе когда это время удачное. А если таких элементов куча, и эти элементы пинают другие элементы, то как ты собрался этот бедлам контролировать?
Может в твоих Vertical Slices подразумевается, что User должен бить челом к пахану и спрашивать его разрешения сохранить в БД, а сам-то User простой мужик и только маляву передает. Иначе это уже беспредел.
>Но если я сделаю класс User, который сам себя в БД пишет, дает доступ из любого места программы ко всему списку юзеров, еще и может отрисовать окошко с редактированием пользователя - пиздец, блядь
Ну как бы да, звучит как ебейший пиздец.
![.png](https://2ch.life/pr/thumb/3097760/17172237947550s.jpg)
> Может в твоих Vertical Slices подразумевается, что User должен бить челом к пахану и спрашивать его разрешения сохранить в БД, а сам-то User простой мужик и только маляву передает. Иначе это уже беспредел.
В том что я читал - подразумевается, что у тебя есть папка Feature, в ней подпапка FeatureName, и вот в этой подпапке - все что нужно чтобы твоя фича самостоятельно была этой самой фичей. Т.е. все константны, все обработчики, события, эндпоинты, эксепшины и прочее. С минимальным уровнем абстракции. Примерно прикриплейд
>>176225
По мне и вот эта вот фигня с папочками - тоже как пиздец выглядит. Но ее уже зафорсили на фронте, и фронтендеры за обе щеки уплетают, говорят - заебись. Я вот хочу разобраться, чем обычная слоеная архитектура - хуже вот этого вот. Они как аргумент постоянно рассказывают, что вот, я с папочкой работаю, все что мне надо - там есть. Я говорю: ИДЕ тебе позволяет по F12 куда надо прыгнуть. Мне говорят: Я В ВСКОЛ/ВИМе пишу. Я хз что на это кроме совета в одном файле все делать ответить.
Ну можешь прыгать прыгай никто не запрещает.
Feature folder рулит. Не нужно никуда прышать, весь контекст в одном месте, всё структурно и позволяет легко дробить на классы не создавая хаос вида "это нужно только этому, но лежит рядом со всеми или отдельно от всех" (оба варианта говно)
Так один класс - еще лучше же в таком случае. Все в одном файле, на🌶. Весь контекст.
И хаоса не будет, если ты нормально структурируешь класс, и как деды - #region'ами разделишь че куда.
Нормально же. Че не так?
А еще лучше - вообще один файл Program.cs на проект - вот там-то вообще будет ВЕСЬ КОНТЕКСТ.
Плюс, с этими фичафолдерами - начинается 🌶ня, как только у какой-то фиче появляется что-то, что хотелось бы в другой фиче использовать. С обычной слоеной архитектурой, у тебя бы был скорее всего генерализованный сервис где-то на уровне application и ты его мог как угодно на всех уровнях выше дергать. С фичаслайсами - начинается 🌶ня: а че делать? Вынесем это в Shared, а вдруг никому больше надо не будет, может просто скопипастишь что тебе надо, ой, там был баг, в 2 местах теперь поправить не забудь.
Короче. Мне чет не оч нравится. Со слоями как-то удобнее.
Ни один из режимов не работает, я же писал.
Не нужно утрировать.
ты и так делишь все на класссы. Просто распихиваешь ЗАЧЕМ ТО связанные логически классы в 100005000 мест только потому что кто КТО-ТО сказал что вот эти классы должны лежать там, а эти там.
Но при этом тебя не удивляет что ты качаешь какую то либу с нюгета, а либа почему то делает что то одно и не говорит тебе "качай миллион либ, я распихал одну функциональность по миллиону мест". Можно же одну мегалибу сделать, удобно же да?
То есть фича пакет для тебя почему то норм. А чем в общем то фича пакет отличается от фича неймспейса? да ничем.
Если ТЕБЕ удобно бегать по всему проекту, то бегай. Другим вот удобно когда все связанное лежит связно. Фича подход не отрицает слои.
>Где вы такое говно откапываете?
У родителей в деревне, ноут из моего детства, хули.
>>175164
>Тут вопрос в том, а должно ли это что-то уметь компилировать код?
Я надеялся что компилятор есть везде, но изучив эту тему теперь я понимаю что в мире программирования всё должно быть через жопу.
>>174879
Люди про него страшные вещи пишут.
>>174859
Пикнул твой вариант, пасиба за совэт. Пишу код в нотпаде++, затем командной строкой его в программу переделываю, затем только запускаю и смотрю чё там внутри. Пиздец конечно, но что поделать.
>Просто распихиваешь ЗАЧЕМ ТО связанные логически классы
Нет. Распихиваются не просто "логически" связанные классы, а по их функционалу. Внутри слоев ты точно так же можешь группировать классы по фичам/домену/желанию левой пятки, просто поддерживаешь везде одинаковую структуру и все.
>затем командной строкой его в программу переделываю, затем только запускаю и смотрю чё там внутри.
Вместо того, чтобы каждый раз вручную писать инструкции в консоль, ты можешь написать батник и компилировать приложение по даблклику на батнике.
Или даже сам себе сделать приложение, которое будет и инструкции отправлять, а потом запускать собранное приложение. Делов на пару вечеров.
Потому что у тебя:
- русифицированная студия
- светлая тема.
А если серьезно, то у тебя просто похоже ResourceView вместо SolutionExplorer включился.
Выбери View -> Solution Explorer, или нажми Ctrl+Alt+L
Есть к примеру сайт, его задача максимально быстро отвечать на запросы. Но также нужно записывать лог в mysql, дату юзер агент и тд и тп. На сколько хороша идея писать в базу асинхронно ?
ну типо
WriteLogAsync(info);
return "example string";
По какому функционалу. Контроллеры отдельно, вьюмодели отдельно, вид (неважно чей) - тоже отдельно, валидаторы отдельно, команды отдельно, хендлеры отдельно - все отдельно. И уже ВНУТРИ их идет деление по фичам либо в имени файла либо в необходимости создания подпапки. В итоге классы для реализации одной фичи размазаны по куче мест. Если тебе это удобно - ну рад за тебя.
Feature Folder противовес этому. Зачем распихивать одну фичу по 100 мест? какую это привносит пользу? типа "если мне нужен хендлер я иду в хендлеры и там ищу"? ну так вон он у тебя хендлер тут лежит в фиче сразу. Ибо не путается среди сотни чужих хендлеров. А если нужно много для фичи - ну так выдели ты подпапку "хендлеры".
И это мы говорим только про навигацию.
А еще возьми ту же модульную архитектуру, где подключение модуля привносит сразу все (и даже его вид). Где лежат части этого модуля? в ТВОИХ семантических папках? нет. они лежат в модуле. Так если эта штука удобная когда делаешь подключаемые модули, то почему вдруг не делать так везде?
Плохая.
1. Ты теряешь тачку
2. Если будет 2-3к рпс сам понимаешь лишняя нагрузка
3. Если это через еф то можно получить исключение что контекст не тредсейф
4. Ты продолжаешь держать скоуп
Складывай в очередь и в каком нибудь хостедсервисе разгребай раз в N секунд батчами
1. Таску
Спасибо.
Тоже вторая идея была накапливать записи к примеру 1к и потом пачками их записывать. А во время записи пачки в бд накапливать новые записи в другой список.
В твоей ситуации юзал SharpDevelop, неплохая штука если студия недоступна по производительности
Блядь, почему ты единственный кто мне про него написал? Идеальный вариант, поставил и всё работает как надо без ебли в жопу. Спасибо, брат, век не забуду.
А все остальные советчики идите в очко блядь, дегенераты ебанные.
>Блядь, почему ты единственный кто мне про него написал?
Потому что последняя версия в 2016-м году была. Тебе вообще повезло, что про него хоть кто-то еще помнит.
Обращайся.
Не за что, чел...
Не за что, дам еще 1 совет - SharpDevelop неплох но когда речь пойдет уже о serious coding то готовься как можно побыстрее проапгредить тачку чтобы нормально работать со студией и вообще если производительность ПК ограничивает тебя в использовании более удобных средств разработки то вливай деньги в апгрейд ПК. Помни что ПК - твой велосипед для мозга, и если этот велосипед тебя тормозит, то это не дело. Говорю как человек который год откладывал апгрейд железа.
А как это реализовано? Когда я делал функционал стакающихся окон (ну когда пользователь мог перетащить одно окно внутрь другого) то я не окна перемещал, а грубо говоря манипулировал юзер контролами внутри окон.
Но в студии как-то по другому сделано. Да в хроме, когда активируется режим "картинка в картинке", и возникает плавающее окно с видео — оно тоже состоит из нескольких окон. Пикрил 2, красная и желтые рамки — это два окна. Пикрил 3 - иерархия.
Есть какая-то технология? Зачем так делать? Почему не перемещать юзерконтролы, ну или просто спавнить новые? MVVM это позволяет.
Я знаю, что при помощи WinApi можно окну указать родителя или владельца. А как это делать средствами WPF или Forms? Я имею ввиду, чтобы не выглядело как костыль.
![SetParent.mp4](https://2ch.life/pr/thumb/3097760/17175337942390s.jpg)
784x884, 0:08
> Но вот как создать окно без режима дизайнера — это уже другой вопрос.
Создать дизайнер через System.ComponentModel.Design.DesignSurface
https://learn.microsoft.com/en-us/windows/win32/winmsg/window-styles
И ладно бы когда функционал тот же самый, типа Minimize и Iconic. Но ведь Group и MinimizeBox вообще никак по функционалу не схожи.
Очевидно что group и minimizebox конфликтуют и имеют применение в разном контексте
У context есть HttpContext у которого есть RequestServices (это скоуп для реквеста). Кури доку
Охуеть, буду знать. Спасибо большое, всё заработало
Там ещё варианты есть. Не знаю даже какой из них лучше
А программисты то реально пидорами оказались
Никогда не было проблем со стилями в wpf. Всё очень легко кастомизируется.
>Всё очень легко кастомизируется.
Если у тебя не было проблем со стилями, то ты просто неглубоко копал. Например попробуй через стиль реализовать поведение ListView, который в зависимости от контекста, мог быть и ListBox и GridView, как это делает ListView с дефолтным стилем.
Или попробуй реализуй систему скинов, подгружаемых из файла.
Я уже молчу про случаи, когда тебе кажется, что все хорошо, но на самом деле все плохо. Например начитавшись вредных советов на SO мерджить словари ресурсов прям в контролах. Особенно это забавно, когда чел поливаясь потом оптимизировал функцию, чтобы сохранить пару килобайт памяти, но после действий с мерджингом, словари одним взмахом кушают 150Мб и не собираются останавливаться.
>>184522
>система стилей в впф говно.
Это просто жертвы ради гибкости, но впф позволяет сделать многое. Есть сырые вещи, типа системы тем, а есть неоднозначные и неинтуитивные, типа "generic.xaml", о которых тебе не скажут, пока не наткнешься случайно. Сложно с впф работать, если каждый раз начинать все с нуля, но если под себя настроить инфраструктуру, то получается легко. Я формсы терпеть не могу.
>Планирую написать клиент двача для винды на wpf, какие подводные?
Подводные в виртуализации.
Во-первых, не все списковые контролы поддерживают виртуализацию. Без виртуализации у тебя все элементы списка будут загружаться разом и где-то после 1тыс. элементов, приложение вовсе зависнет. В режиме отладки есть окно, которое показывает иерархию контролов — хорошо по нему проверять вот такие вот проблемы.
Во-вторых, если начнешь делать подсветку текста, то скорее всего начнешь пробовать RichTextBox, а он изначально в WPF не создан для больших объемов текста (я вообще не знаю для чего). Это огромная проблема, которая до сих пор не решена. Для этого даже сделали либу, не помню как называется, но она позволяет делать подсветку синтаксиса в впф. Но там тоже надо покурить мануал и попариться. Многие редакторы основаны на это либе, например Sublime Text.
Кажется библиотека называется AvalonEdit
> Многие редакторы основаны на это либе, например Sublime Text.
Сомневаюсь, sublime text старше этой либы и не использует wpf.
>>184751
> Например попробуй через стиль реализовать поведение ListView, который в зависимости от контекста, мог быть и ListBox и GridView, как это делает ListView с дефолтным стилем.
Не вижу смысла реализовывать такое через стили, когда есть темплейтселектор
Лучше возьми Eto.Forms.
потому что явное применение стиля к контролу напрочь ломает неявные стили. И нужно брать бубен и плясать в неудобное наследование.
Также невозможно нормально создать либу и указать "вот ищи стиль тут у меня, я либа, я гуишная твою мать либа и у меня есть стили которые нужны лично мне, дай мне скоуп для этого" - хрен тебе. нужно все в App.xaml добавлять иначе IDE не видит нихрена, и само добавление подразумевает мерж стилей, что как бы вообще не то что надо.
>И нужно брать бубен и плясать в неудобное наследование.
В чем заключается неудобство?
>Также невозможно нормально создать либу и указать "вот ищи стиль тут у меня, я либа, я гуишная твою мать либа и у меня есть стили которые нужны лично мне, дай мне скоуп для этого"
Можно. Для этого ты должен соблюсти два требования:
1. твой стиль должен находиться в проекте по адресу Themes\generic.xaml (либо в том словаре мерджиться), потому что это место по-умолчанию, где будут искаться недостающие стили.
2. В статическом конструкторе надо переопределить стиль.
Кроме того, ты можешь стиля передавать внутрь своего класса темплейты по имени. Наверно ты видел в шаблона, когда обязательно дают контролу имя по типу "PART_blablabla". В классе вызывается событие OnApplyTemplate, в котором по указанному имени можно и получить экземпляр на этот контрол. Так примеру работает Slider, где ты указываешь контейнер для элемента ползунка, а класс слайдера может это ползунок двигать.
Единственный минус всего этого — это все делается дооолго. Но зато можно кастомизировать что угодно.
>В чем заключается неудобство?
Его нужно указывать явно. Для этого нужно знать что указать. А если ты в либе и просто не знаешь имени будущего стиля в приложении? завязываться на дефолтный стиль глупо ведь на то он и дефолтный. Оставлять записку "будь добр создай вот этот стиль вот тебе ключ такой" бррр дичь.
>Можно. Для этого ты должен соблюсти два требования
ты путаешь стили для кастомного контрола если я пишу его по всем правилам и просто стили. В либе просто НЕКУДА поместить стиль чтобы студия на него не ругалась если ты не положил его в ресурсы App.xaml в итоге. И насрать студии что стиль будет доступен в рантайме.
И мерж словарей с совпадающими ключами....нужно выдумывать ключи типа MySuperLib_TheSyle? Бредятина
>Кроме того, ты можешь стиля передавать внутрь своего класса темплейты по имени
А это вообще не про стили
>ну и он конечно не может наследоваться от 2+ стилей
Это как? У одного стиля бэкграунд черный, у другого — красный. На какой сам сядешь, на какой мать посадишь?
сказал он написав ответ в браузере, который отображает страницу которая имеет развитую систему стилей в которой такая коллизия сплошь и рядом, но почему то победил не хамл, а веб
>И мерж словарей с совпадающими ключами....нужно выдумывать ключи типа MySuperLib_TheSyle?
А как надо? Если ты хочешь переопределить ресурс, то добавляешь ресурс с тем же ключом. Если ты хочешь новый ресурс, то называешь по новому.
У меня вроде как по началу тоже горело, и я хотел видеть что-то виде неймспейсов. Я помню, что меня бесило, что какой-то локальный ресурс был виден во всем приложении. Но потом вроде как смирился.
не хочу. пусть это тебе фронтендеры поясняют. я веб знать не хочу. но я прекрасно вижу ограниченность стилей в WPF. Я обычно не попадаюсь ибо мне срать на темы, но даже мне приходится иногда мудрить - например делать пустые стили лишь бы им имя дать лишь бы их указать в Style={Static...потому что нужно разделение. Это костыли
>>186282
я не хочу ничего переопределять. Я просто хочу использовать стили. свои, и, для, себя.
Допустим, я пишу либу. В ней я хочу использовать обычные стили которые используются как Style={Static...
И возникает обычный вопрос - а куда все это добро класть?
А ответа нет. Потому что у либы в его юзерконтроле нет родительского чего нибудь в иерархии. А раз нет, значит студия не может найти определение стиля.
Решение для аппки - запихать все это в итоге в App через мерж словарей (и вот тут возникнет вопрос коллизии имен, но внутри аппки это решается ибо ты сам себе пишешь)
Но вот в либе у тебя жопца - и начинаются костыли о которых регулярно тут всплывает
- раз у нас нет иерархии, значит....впихнем все в словарь и это словарь укажем в ресурсах каждого б...ь контрола
- а поскольку дробление суперпортянок хамл неизбежно, то этих контролов может быть много
- ой блин, так каждый такой словарь дублируется в памяти. идем на со искать как не дублировать словари
и читаем 100500 тем на эту тему с сотней костылей.
БЛЯДЬ, ЭТО ЧТО, ПРАВДА? СКИНЬ ССЫЛКУ, ПИЗДЕЦ!
![2024-06-1016-14-20.png](https://2ch.life/pr/thumb/3097760/17180257874160s.jpg)
>Очень легко, применяется цвет в последнем указанном стиле
Так в WPF тоже самое.
Если у тебя два ресурса с одинаковым ключом, то возьмется самый последний ресурс. Но это не является множественным наследованием стилей.
>>186329
>Допустим, я пишу либу. В ней я хочу использовать обычные стили которые используются как Style={Static...
Во-первых, шатать стили — не зона компетенции библиотек. Этим занимается конечное приложение, которое определяет итоговый стиль контролов.
Единственный случай, когда стиль допускается в библиотеке, это если ты создаешь собственный контрол, либо наследуешь существующий. Вот тогда ты пихаешь базовый стиль в Themes\generic.xaml. И уже потом, приложение, которое этот контрол использует, переопределяет стиль на свой собственный, либо юзает базовый.
Во-вторых, статик — говно, если ты уж хотел что-то динамичное. У тебя куча функционала просто отваливается. Ты не сможешь в одном словаре определить цвета, чтобы другие словари ими пользовались — а на этом и основана дизайн-система. Ты не можешь в риалтайме менять словари ресурсов. Статическая привязка типа должна экономить ресурсы, но по факту эта экономия либо нулевая, либо условная.
Возможно вся ненависть к WPF и основана на том, что ты юзаешь статик ресурсы.
>не хочу. пусть это тебе фронтендеры поясняют.
На фронтенде используют дизайн-систему и все ей подчиняются. Дизайн-система определяет четкие названия ключей, по типу пирилейтед. А то что в твоих проектах она отсутствует — это все равно что сказать "да мне пох на бэкенд, эти ваши паттерны и кодстайл, я тут насрал, там насрал, и у меня появились проблемы. Значит ваш бэкенд говно!".
>раз у нас нет иерархии
Есть. Объединяемые словари не сливают ресурсы в единый список. Они хранятся в отдельном списке MergedDictionaries, который есть у каждого словаря, и в этих списках могут быть ссылки на другие словари, у которых тоже есть MergedDictionaries. Это и есть иерархия. Ты эти словари можешь отключать и подключать. У меня на этом основан менедежер тем и скинов.
![2024-06-1016-14-20.png](https://2ch.life/pr/thumb/3097760/17180257874160s.jpg)
>Очень легко, применяется цвет в последнем указанном стиле
Так в WPF тоже самое.
Если у тебя два ресурса с одинаковым ключом, то возьмется самый последний ресурс. Но это не является множественным наследованием стилей.
>>186329
>Допустим, я пишу либу. В ней я хочу использовать обычные стили которые используются как Style={Static...
Во-первых, шатать стили — не зона компетенции библиотек. Этим занимается конечное приложение, которое определяет итоговый стиль контролов.
Единственный случай, когда стиль допускается в библиотеке, это если ты создаешь собственный контрол, либо наследуешь существующий. Вот тогда ты пихаешь базовый стиль в Themes\generic.xaml. И уже потом, приложение, которое этот контрол использует, переопределяет стиль на свой собственный, либо юзает базовый.
Во-вторых, статик — говно, если ты уж хотел что-то динамичное. У тебя куча функционала просто отваливается. Ты не сможешь в одном словаре определить цвета, чтобы другие словари ими пользовались — а на этом и основана дизайн-система. Ты не можешь в риалтайме менять словари ресурсов. Статическая привязка типа должна экономить ресурсы, но по факту эта экономия либо нулевая, либо условная.
Возможно вся ненависть к WPF и основана на том, что ты юзаешь статик ресурсы.
>не хочу. пусть это тебе фронтендеры поясняют.
На фронтенде используют дизайн-систему и все ей подчиняются. Дизайн-система определяет четкие названия ключей, по типу пирилейтед. А то что в твоих проектах она отсутствует — это все равно что сказать "да мне пох на бэкенд, эти ваши паттерны и кодстайл, я тут насрал, там насрал, и у меня появились проблемы. Значит ваш бэкенд говно!".
>раз у нас нет иерархии
Есть. Объединяемые словари не сливают ресурсы в единый список. Они хранятся в отдельном списке MergedDictionaries, который есть у каждого словаря, и в этих списках могут быть ссылки на другие словари, у которых тоже есть MergedDictionaries. Это и есть иерархия. Ты эти словари можешь отключать и подключать. У меня на этом основан менедежер тем и скинов.
> Если у тебя два ресурса с одинаковым ключом, то возьмется самый последний ресурс. Но это не является множественным наследованием стилей.
Потому что применяется только последний стиль. А в css, применятся все указанные стили, перезаписывая свойства, если они встречаются в нескольких стилях.
> Ты не сможешь в одном словаре определить цвета, чтобы другие словари ими пользовались — а на этом и основана дизайн-система
Спокойно сможет, главное этот словарь включить в app.xaml , перед другими словарями
>У меня на этом основан менедежер тем и скинов.
У меня ресурсы разбиты на отдельные словари:
- Есть словарь, где хранится цветовая схема приложения т.е. это условно 20 цветов, которые абстрактно описывают цвет всего интерфейса.
- Есть словарь, где хранятся радиусы элементов, данные о шрифтах и т.д.
- Контролы хранятся отдельно и при помощи динамической привязки ожидают ключи из первых двух словарей.
Дальше менеджер скинов, который наследует ResourceDictionary внутри комбинирует словари по моим условиям. Этот менеджер добавляется в App.xaml
Система чуть сложнее, потому что есть куча прослоек, чтобы скин можно было более тонко настроить, чтобы к примеру менять контрастность интерфейса при одной и той же цветовой схеме.
>Потому что применяется только последний стиль. А в css, применятся все указанные стили, перезаписывая свойства, если они встречаются в нескольких стилях.
Знаешь про "BaseOn"?
Но я не несу хуйню, приплетая basedon, когда речь идет о поддержке множественных стилей.
>Во-первых, шатать стили — не зона компетенции библиотек
Стили не только средство изменения внешнего вида. А средство избавления от копипастинга и много чего. Внешнему приложению просто нет до этого дела. Поэтому эти стили и ИМЕЮТ x:Key ибо предназначены исключительно для того, для кого предназначены.
>если ты уж хотел что-то динамичное
вообще не говорил про динамику. ни слова. Моя претензия к системе стилей вообще - невозможность определить скоуп, невозможность разделять стали по функционалу и потом свести их воедино (BasedOn указывает только одного родителя), необходимость запихивать все в одну точку поиска по имени.
>ты юзаешь статик ресурсы
Ненависть у меня ко всему подходу где что-то может компилироваться, но при этом в рантайме тихо проглотит ошибку. Или, наоборот, из-за одной проблемы в ошибках будет каскадных сотня ошибок и хрен поймешь где реально ошибка (ее может даже не быть в окошке Errors O_O). Или когда БАЗОВЫЕ контролы сделаны так что ради изменения фона выделения нужно перегружать весь шаблон.
Еще раз - Themes\generic.xaml это про темы. Если я помещу туда стиль с x:Key то я НЕ МОГУ использовать его в ЭТОЙ ЖЕ либе как StaticRes. Студия просто его не найдет - будет подчеркивать, не смогу перейти по клику, не будет работать дизайнер. DynamicRes не является лечением этого, да и StaticRes в рантайме отработает. Это не проблема статик/динамик. Это фундаментальное отсутствие работы с этим без костылей.
>А то что в твоих проектах она отсутствует
вообще не понял что ты тут нагородил. я просто сказал что я не фронтендщик и не знаю как там решают проблемы имен. Однако я достаточно осведомлен чтобы знать что CSS позволяет навесить миллион классов на элемент и там есть такое понятие как локаторы "элемент Б лежит в элементе А - вот он нам и нужен, а не любой элемент Б". Возможно там сверхгибкость, но в WPF явный недостаток гибкости
>Они хранятся в отдельном списке MergedDictionaries
Ну иерархия вместо плоского списка...ну ок
Как это влияет на разрешение стилей по именам? А никак. 2 стиля с одним именем играют в маклаудов.
>Во-первых, шатать стили — не зона компетенции библиотек
Стили не только средство изменения внешнего вида. А средство избавления от копипастинга и много чего. Внешнему приложению просто нет до этого дела. Поэтому эти стили и ИМЕЮТ x:Key ибо предназначены исключительно для того, для кого предназначены.
>если ты уж хотел что-то динамичное
вообще не говорил про динамику. ни слова. Моя претензия к системе стилей вообще - невозможность определить скоуп, невозможность разделять стали по функционалу и потом свести их воедино (BasedOn указывает только одного родителя), необходимость запихивать все в одну точку поиска по имени.
>ты юзаешь статик ресурсы
Ненависть у меня ко всему подходу где что-то может компилироваться, но при этом в рантайме тихо проглотит ошибку. Или, наоборот, из-за одной проблемы в ошибках будет каскадных сотня ошибок и хрен поймешь где реально ошибка (ее может даже не быть в окошке Errors O_O). Или когда БАЗОВЫЕ контролы сделаны так что ради изменения фона выделения нужно перегружать весь шаблон.
Еще раз - Themes\generic.xaml это про темы. Если я помещу туда стиль с x:Key то я НЕ МОГУ использовать его в ЭТОЙ ЖЕ либе как StaticRes. Студия просто его не найдет - будет подчеркивать, не смогу перейти по клику, не будет работать дизайнер. DynamicRes не является лечением этого, да и StaticRes в рантайме отработает. Это не проблема статик/динамик. Это фундаментальное отсутствие работы с этим без костылей.
>А то что в твоих проектах она отсутствует
вообще не понял что ты тут нагородил. я просто сказал что я не фронтендщик и не знаю как там решают проблемы имен. Однако я достаточно осведомлен чтобы знать что CSS позволяет навесить миллион классов на элемент и там есть такое понятие как локаторы "элемент Б лежит в элементе А - вот он нам и нужен, а не любой элемент Б". Возможно там сверхгибкость, но в WPF явный недостаток гибкости
>Они хранятся в отдельном списке MergedDictionaries
Ну иерархия вместо плоского списка...ну ок
Как это влияет на разрешение стилей по именам? А никак. 2 стиля с одним именем играют в маклаудов.
>Но я не несу хуйню
Ты не можешь сформулировать ответ на вопрос как происходит работа с наследованием нескольких стилей? А потом рвешься. Все твои ответы выглядят так, как будто речь идет о последовательном переопределении одного стиля.
Я тебе ответил, что свойства из стилей применяются в порядке указания самих стилей (а точнее классов, на которые эти стили нацелены). Таким образом при наличии одного и того же свойства в нескольких стилях будет использоваться его значение из стиля, указанного позже. Ты в ответ зачем-то написал про BasedOn, хотя это банальное наследование стиля и не имеет никакого отношения у обсуждаемой теме указания более чем одного стиля для элемента.
>Однако я достаточно осведомлен чтобы знать что CSS позволяет навесить миллион классов на элемент и там есть такое понятие как локаторы "элемент Б лежит в элементе А - вот он нам и нужен, а не любой элемент Б". Возможно там сверхгибкость, но в WPF явный недостаток гибкости
Почему еще не перекатился в Avalonia? Там всё это есть
>Еще раз - Themes\generic.xaml это про темы.
Это не про темы. Там хранится дефолтный стиль твоего контрола, который будет обнаружен даже без добавления в App.xaml
> 2 стиля с одним именем играют в маклаудов.
Ничто там не играет. Берется последний стиль в списке.
Если я не хочу перезаписывать стиль целиком, то я просто использую BasedOn.
>Как это влияет на разрешение стилей по именам?
Я ответил на вопрос.
>вообще не говорил про динамику.
Ну ты не говорил, но тебе нужно.
>Внешнему приложению просто нет до этого дела.
>Поэтому эти стили и ИМЕЮТ x:Key
Я не понимаю что ты хочешь. Хранить стили в библиотеке ты можешь. Твое предыдущее сообщение выглядит так:
>В либе просто НЕКУДА поместить стиль чтобы студия на него не ругалась если ты не положил его в ресурсы App.xaml
Ты можешь последовательно описать чего ты хочешь добиться? Получить ты этот стиль из любого места тоже можешь.
шрифты в авалонии убогие. Ну да это проблема Skia, но проблема есть проблема. А еще если глянуть на примеры селекторов в их доке то не особо видно "в КОНКРЕТНОМ онтроле А есть контрол Б" могут ли они так.
>>187089
>будет обнаружен даже без добавления в App.xaml
чушь. упадет сразу в рантайме при попытке разрешить StaticRes.
>Ничто там не играет. Берется последний стиль в списке.
Это и есть маклаудизм. "выживет только один".
>Если я не хочу перезаписывать стиль целиком, то я просто использую BasedOn.
у тебя в огороде бузина
есть 2 либы. у каждой есть СВОЙ стиль x:Key="FooStyle". Причем тут BasedOn?
>Я ответил на вопрос.
Нет. это я ответил - НИКАК. Внутреннее хранение смерженных словарей НИКАК не относится к проблеме коллизии имен. Ах да - "берется самый последний стиль". так это и есть проблема коллизии и "выживет только один" - НЕ ЯВЛЯЕТСЯ РЕШЕНИЕМ!!!!!!!!!!!!!!!!!!!, а собственно является проблемой
(я достаточно много поставил !!! чтобы ты наконец перестал выдавать ПРОБЛЕМУ как решение?). Или ты из тех которые на вопрос "так это ж нужно жрать говно" говоришь "но это же описано в документации значит нормально"?
>Хранить стили в библиотеке ты можешь
Хранить могу. Получить НЕ МОГУ. Они НЕ БУДУТ работать ибо не будут найдены пока я не добавлю их и в то место, где их будут искать. Никакого автоматического поиска в generic не будет (да и вообще не должно бы ведь это USERConrol-ы, у них нет дефолтных стилей). Значит нужно куда то явно добавлять. А в случае либы таких мест всего 2
1 - App.xaml с его мержем словарей (и насрать иерархия это или что). из 2х одинаковых имен выживет только один. В ЭТОМ И ЕСТЬ ПРОБЛЕМА!! (и тут миллион !)
2 добавить в ресурсы самого контрола чтобы "тут же и нашел именно МОЙ стиль, а не чужой выживший". Но тогда происходит дублирование словарей в памяти.
![image.png](https://2ch.life/pr/thumb/3097760/17180342363970s.jpg)
>шрифты в авалонии убогие. Ну да это проблема Skia, но проблема есть проблема.
Только если специально сранивать. Да и вообще поебать, не мне апой пользоваться...
>А еще если глянуть на примеры селекторов в их доке то не особо видно "в КОНКРЕТНОМ онтроле А есть контрол Б" могут ли они так.
Буквально один из первых примеров
и речь не про стиль юзерконтрола, а то ты можешь и к этому придраться
речь про общие стили которые нужны элементам внутри моей либы. Это обычные ...что угодно в общем то поэтому и x:Key
>Только если специально сранивать
там шрифты больше поэтому, а значит потребляют больше места.
а значит меньше поместится в ту же таблицу на экране
>Буквально один из первых примеров
в упор не вижу в примере где там про "конкретный вот ЭТОТ StackPanel, а не любой"?
> в упор не вижу в примере где там про "конкретный вот ЭТОТ StackPanel, а не любой"?
Что ты понимаешь под конкретно этот? Можешь добавить селектор имени. Но вообще для таких целей определяют стиль в ресурсах конретно этой StackPanel
>чушь. упадет сразу в рантайме при попытке разрешить StaticRes.
Это не чушь, это официальная рекомендация.
>есть 2 либы. у каждой есть СВОЙ стиль x:Key="FooStyle".
Именно по этой причине я и писал, что за конечный стиль отвечает приложение, а не библиотека. А в Themes\generic.xaml базовый стиль определяется без ключа.
>Это и есть маклаудизм. "выживет только один".
Хуже когда стиль внезапно модифицировался, и ты этого не ожидал. Потом ищи что на что повлияло и когда.
>Можешь добавить селектор имени
ну банальщина же для css
#thispanel > button.red
>Но вообще для таких целей определяют стиль в ресурсах конретно этой StackPanel
ага. и получаем мегапортянку. потом разбиваем портянку на отдельные элементы и каждому свой хамл и оппа - оказывается что эти элементы знать не знают ни про какого родителя в компильтайме. В итоге толку от IDE как от блокнота. все же любят писать статически типизированный код в блокноте, ведь так же )
>>187140
я (надеюсь тебе) говорил что если в документации написано "жрите говно", то это не значит что это хорошее решение. Смекаешь? (видимо риторический вопрос ибо ты не смекаешь).
Так и напрашивается тут одно средство передвижения из мультфильма "южный парк" с особым способом крепления водителя ибо "так задумано, а значит правильно" )))))
>>187140
>за конечный стиль отвечает приложение, а не библиотека.
я, автор библиотеки А, определяю свой стиль и ок разрешаю приложению его переопределить если ему так хочется.
Автор библиотеки Б делает то же самое и знать не знает про библиотеку А.
А ты, как приложение, должен теперь решить как тебе усидеть на двух стульях.
>Themes\generic.xaml базовый стиль определяется без ключа.
отличай стили по типам и по ключам. Если у типа еще есть понятие "свой элемент" ибо у типа есть нейспейс, то стиль по ключу применяется к общему элементу у которого нет никакой уникальности. Поэтому и нужен ключ, чтобы не применялось ко всему на свете.
>>187140
Или, наоборот, должно работать, а ничего не произошло. И иди ищи. Как тебе в обоих случаях поможет IDE? а никак. в браузере же хоть и лютая дичь, но есть F12 где можно посмотреть кто повлиял, а кого нах послали.
ну а я сказал что может и есть, но в доке это не очевидно ибо в примерах нет.
в любом случае шрифты говно и это не изменить.
И вообще выглядит уг по скиа-шному
> ну а я сказал что может и есть, но в доке это не очевидно ибо в примерах нет.
Ты просто не очень умный, бывает. В доке есть пример селектора имени и селектора дочерних элементов, чтобы сложить 2 + 2 не нужно иметь семи пядей во лбу.
Вообще то из первого второе не следует. И если для тебя это следует, то это ты не очень умный.
И можно легко быть как ты, а потом с удивлением узнать что оказывается система селекторов там СВОЯ, а не так как ты ожидаешь посматривая на css
ну да, бывает, что фантазируешь на тему. Вон мой оппонент фантазирует что стили в впф удобные.
> Вообще то из первого второе не следует.
Конечно же следует, ведь каждый селектор это в сущности выражение linq, возвращающее перечисление, и возможность их комбинировать, применяя последовательно, это само собой разумеющийся функционал
нет не следует.
то что в примере подается
<Style Selector="StackPanel > Button">
как эквивалент
new Style(x => x.OfType<StackPanel>().Child().OfType<Button>());
это НЕ значит что выборка по id будет точно так же транслирована. А если для тебя значит, то тест на логику ты провалил
Вот "на LINQ можно написать более точный селектор на который способен LINQ" - вот это да, значит. Но это не значит что DSL селектора за тебя напишет этот LINQ
И кстати про LINQ. Я вижу там LINQ и если он реально LINQ....то это работа с коллекциями. Поиск по айди в коллекции с помощью LINQ имеет сложность O(n).
Сильно не уверен что в css так же, вернее уверен что не так, ибо в DOM можно быстро найти по айди не обходя все дерево. А значит в авалонии скорее всего нет искаробочного решения такого. Поэтому и в доке нет. Решение через LINQ по природе костыль причем тормозной.
> это НЕ значит что выборка по id будет точно так же транслирована. А если для тебя значит, то тест на логику ты провалил
Во первых с чего она должна работать иначе, будь ддя каждого селектора отдельная костыльная логика, это не позволило бы реализовать их композицию. Во вторых там буквально есть пример того, как работает выборка по имени
> x.Name("myButton")
>если в документации написано "жрите говно"
Это ты жрешь говно, пытаясь в базовый стиль пихать глобальные ресурсы, да еще и при помощи статической привязки.
>я, автор библиотеки А, определяю свой стиль и ок разрешаю приложению его переопределить если ему так хочется.
Бля, да для этого и сделали Themes\generic.xaml
Если отрицаешь, то не жалуйся.
>отличай стили по типам и по ключам.
>Поэтому и нужен ключ, чтобы не применялось ко всему на свете.
Ты чет вообще не догоняешь. Ты создал себе контрол типа MyControl. В Themes\generic.xaml создаешь стиль, где в качестве ключа и таргет тайпа указываешь {x:Type xxx:MyControl}. И куда бы ты теперь не подгрузил либу, твой MyControl будет имет базовый стиль, который ты можешь переопределять как угодно потом.
Базовый стиль нужен чтобы просто отобразить твой контрол, как кнопку ты добавляешь и она уже имеет какой-то цвет и форму. Нахуй ты срешь себе в штаны ключами?
>пытаясь в базовый стиль пихать глобальные ресурсы, да еще и при помощи статической привязки.
Да ты упорот. причем тут статическая привязка вообще????????????????? что статическая. что динамическя - РАБОТАЮТ О-Д-И-Н-А-К-О-В-О в рантайме если нужно стиль навесить один раз.
Не всем нужна смена темы в рантайме. И динамика тоже. Но конкретно в этом случае она НЕ ПРИЧЕМ.
>Бля, да для этого и сделали Themes\generic.xaml
Я по моему на русском пишу. И по моему понятно написал что стиль с ключем помещенный туда не виден нигде без добавления этого файла явно в App.xaml что в общем то и делается ибо "а что еще делать если другого варианта нет"
>Ты создал себе контрол типа MyControl
Ты достал. я не знаю как ты читаешь
я ему говорю про случаи
<Button Style="{StaticResource MyStyle}"
причем тут вообще создание контрола.
А про создание контрола это типа про АВТОзагрузку Themes\generic.xaml которая к этому не имеет никакого отношения
Какова ситуация в российском вебе/ентерпрайзе и насколько котируется C# вне гейдева? Или тут рынок также перегрет и лучше забыть о C# и вкатываться во что-то друге, ну или дрочить юнити до сеньерства?
Сколько стаж? Если есть 2+ честного то просто открывай резюме и жди звонков
А что там с Unigne? Он тоже на шарпе.
>в российском вебе/ентерпрайзе и насколько котируется C# вне гейдева
Нормально. Как минимум половина от того объема, что занимает Java.
Но только сразу скажу, весь твой опыт в C# на юнити - нифига не котируется в вебе. Даже в чистом бэкенде.
> Но только сразу скажу, весь твой опыт в C# на юнити - нифига не котируется в вебе. Даже в чистом бэкенде.
А если опыт на wpf?
опыт впф в бэкенде роли не играет (хотя по факту бэкенд это фигня если писал на любых RoR подобных фреймворках на любом языке)
впф хорошо идет там где это внутренний продукт.
Может быть дело в том, что я слишком уж привык к ангулярам-реактам-вью в качестве фронтенда. Но реально - неудобно и больно. Плюс - пугает количество открытых ишью с багами по поводу мемориликов, и ответы в духе - мы не будем это фиксить, если таки хотите фикса - покупайте расширенную поддержку.
В связи с этим вопрос. Кто-нибудь дружил .net приложение с электроном у которого используется какой-нибудь фреймворк, а не Electron.NET который хочет разор-пейджи?
Просто как-бы я понимаю концептуально как подружить. Но у меня тупые вопросы возникают, типа - вот я хочу, чтобы порт для взаимодействия приложений - автоматически присваивался при старте и потом они друг с другом общались. Я хочу - вебсокеты, чтобы "сервер" о своем состоянии клиенту говорил, я хочу чтобы к "серверу" только одно приложение могло приконнектиться и куча остальных тупых вопросов. Но при гуглеже связки .net + electron мне либо хардкод попадается, где предположение, что порд 6666 всегда свободен, либо Electron.NET который с разорпейджами работает.
Спасибо
ничего не поделаешь. все в мире есть говно.
Для меня вот говножс и все что рядом с ним говно. Не в обиду всяким говнореактам, говноангуларам (хотя я обожаю жетпак компоуз у которого подобный подход, но там все же убогий говножс/говнодарт/говно-любойтрансляторвжс)
И если нужен уи то это выбор среди говна. Либо что то к чему то приколочено, либо огорожено, либо дичь.
Для меня вот самая няшность это jetpack compose с его выразительностью, гибкостью и главное статической типизацией (все описывается кодом, никаких вам хтмл, хмл, ммм, смс и прочее). Но...это котлин, да и только под мобилу если. На десктопе гуи нужен то побогаче.
А что впф что авалония что ваши электроны особенно - говно говна. Но сам сижу на впф ибо хоть оно говно, но все же дает достаточную свободу без необходимости костылить клиент серверное приложение будто я имбецил какой.
(была надежда на мауи что они таки сделают MVU с описанием уи кодом (хотя бы такой убогий как флаттер), но они все просрали)
поправка. "но там же убогий говножс" - это относится к реактам и прочему
в жетпак компоуз котлин - а это язык со статической типизацией и мощными возможностями типа скоупов, от чего получается "няяяя". (эх шарпу был это, но у них "мы делаем жаву с сахаром, а когда не делаем то упарываемся в байтоебство.")
> [Flags]
> public enum MyEnum : int
> {
> . . . None = 0, // 0000 0000
> . . . Primary = 1 << 0, // 0000 0001
> . . . Secondary = 1 << 1, // 0000 0010
> . . . Tertiary = 1 << 2, // 0000 0100
> }
Я хочу создать универсальный метод объединения флагов enum:
> public static void AddFlags<T>(this T targetFlag, params T[] addedFlags) where T : Enum
> {
> . . . for (int i = 0; i < addedFlags.Length; i++)
> . . . {
> . . . . . . targetFlag |= addedFlags;
> . . . }
> }
но генерики отказываются воспринимать операторы.
Есть вариант через dynamic:
> targetFlag |= (dynamic)addedFlags;
Есть решение более производительное?
- ансейф
- каст к лонгу
- через values as underlying type
Но в целом задача звучит бессмысленно
+
Кстати, здорово придумали с фейковым шарпотредом на первой странице, шизики высираются там и не доползают сюда.
Ты лучше вкатуну (мне) поясни какой положняк, а то ты (или не ты) вяло пошутил про 1с.
Получаю enum флаги стиля окна через win32 api, но метод ToString() вместо списка флагов выводит число.
Беру этот же enum и комбинирую флаги вручную и теперь ToString() отрабатывает ожидаемо: выводит список названий флагов.
Пикрил 1: код
Пикрил 2: вывод в печать
Одно и то же перечисление, одно и то же число, но результат ToString() разный.
спасибо
Конечно. Именно поэтому я и сижу в шарпотредах.
>Ты лучше вкатуну (мне) поясни какой положняк, а то ты (или не ты) вяло пошутил про 1с.
Если ты трясун ("ой, а вдруг запретят"), то тебе в 1С. Если ты ровный пацан, то учишь, ищешь работу, устраиваешься, работаешь.
Нет перспектив, гроб гроб кладбище пидор!
Каждое скачивание дотнета теперь стоит 15 рублей, все вакансии сократили, дотнетчикам в подворотне ебало бьют.
Вкатывайся в джаваскрипт и хайлоад на ноде, не прогадаешь
>Мне нужно из комбинации флагов удалить флаг и делаю я это достаточно редко, чтобы вспоминать как это сделать.
Чем тебя вариант с маской по AND не устраивает?
Я видел вот такой пример:
>sourceFlag &= ~targetFlag;
Через месяц я забуду как это делать. Не очень частая конструкция.
Мне нехуй было делать, поэтому, вот, generic методы для "|" енумов (всё тестил на .NET 8).
Пик 1: .NET 8, самый эффективный.
Пик 2: pre .NET 8, чуть-чуть менее эффективный (лишние zero extension на типах меньше int).
JIT всё соптимизирует до простого "x | y".
> public static void AddFlags<T>(this T targetFlag, params T[] addedFlags) where T : Enum
> params
> Есть решение более производительное?
Лол.
Весь метод (AddFlags) это говно без задач, не используй его, ну или хотя бы не используй params, если тебе нужна эффективность.
Но я всё же проверил его (с константами и ожидал на выходе константу; метод кстати с ошибкой: или targetFlag по ref, или возвращай T) и JIT инлайнит метод, но: цикл остаётся, массив остаётся, как и чтение из него.
>Через месяц я забуду как это делать.
Я хуй знает как такое забыть. Это ж база, как таблица умножения.
Даже нет - еще проще. Это как базовые правила сложения/умножения. Просто логика, бля.
А зачем столько приведений типов? Возьмем к примеру x
(sbyte)(object)(х)
И зачем x взят в скобки? Дальше вообще тройное приведение
(T)(object)(sbyte)
Я так понял напрямую (sbyte) в (T) не получается, но разве object не порождает аллокации? Это эффективнее dynamic?
Не, ну я конечно разобрал пример
> 0000011000001000 //типа есть у нас набор флагов
> 0000000000001000 //мы хотим удалить этот флаг
> 1111111111110111 //при помощи тильды инвертируем
> далее при помощи AND сравниваем биты
> 0000011000000000
> в итоге незатронутые нули единицы такими и остаются, а
> инвертированная единица превращается в ноль
Но я побитовые операции не использую часто и в итоге опять буду гуглить (и я уже гуглил когда-то, но забыл). Проще метод сделать и забыть.
> И зачем x взят в скобки?
Так получилось, можно убрать.
> Я так понял напрямую (sbyte) в (T) не получается, но разве object не порождает аллокации?
Нет, не порождает.
> Это эффективнее dynamic?
Да
Вообще (<тип>)(object)(<пер_типа_T>) и (T)(object)(<пер>) относительно известные конструкции в generic коде, JIT нормально их оптимизирует. Но такие конструкции порождают большой IL, поэтому JIT инлайнит их плохо, поэтому нужно AggressiveInlining.
Если что, то генерируемый код я смотрел в sharplab, а потом уже в VS2022, .NET 8.0.5, X64, COMPlus_JitDisasm=*
Например код для StringSplitOptions, как generic метода так и у обычного:
> mov eax, ecx
> or eax, edx
> ret
![image.png](https://2ch.life/pr/thumb/3097760/17183015536790s.jpg)
Вот ещё, к слову другие варианты (пик).
Они все эффективны (по крайней мере на .NET 8).
Я даже хз какой вариант лучше, ведь, например, (sbyte)(object) - странно, ведь реальный тип T не sbyte, а какой-то enum. BitCast требует struct (в .NET 9 не будет). int/uint вариант - странная каша из (T)(object) и указателей. long/ulong вариант не такой компактный, как int/uint вариант.
К слову всё это максимально эффективно, пока типы совпадают. А то в >>190608 на 2-ом пике, когда в метод приходят sbyte и short, код немного хуже, т.к. типы не совпадают а JIT тупой и вместо 3-х инструкций получается 5.
>Но я побитовые операции не использую часто и в итоге опять буду гуглить (и я уже гуглил когда-то, но забыл).
>Проще метод сделать и забыть.
Серьезно? Т.е. по твоему проще наворотить мутантов как тут >>190724 или тут >>190608 , чем запомнить простые конструкции вроде 1&1=1 или 1&0=0 и т.д. Там буквально три функции AND, OR, NOT. Все остальное это их комбинации.
Ну я потому и написал в тред, чтобы понять насколько это целесообразно. А так я просто сделаю пометку себе в журнале.
Ну и новое узнал сегодня, спасибо анону >>190724
>>190608
>Там буквально три функции AND, OR, NOT.
Да если бы я по десять раз на дню это юзал, применительно к байтам. Если я что-то использовал один раз и не записал это, то моментально вылетает из головы.
даже в JetBrains их запоминать не хотят и у них есть хелпер класс для битовых полей
Бамп вопросом
Почему если комбинировать флаги перечисления через оператор OR
> WindowStyleFlags windowStyles1 = WindowStyleFlags.SysMenu | WindowStyleFlags.ClipChildren;
метод windowStyles1.ToString() выдает список имен флагов "SysMenu, ClipChildren",
а если присвоить число, которое представляет из себя комбинацию все тех же флагов
> WindowStyleFlags windowStyles2 = (WindowStyleFlags)(34078720);
метод windowStyles2.ToString() выдает число "34078720"?
напоминаю что:
> (WindowStyleFlags.SysMenu | WindowStyleFlags.ClipChildren) == 34078720
Загадка дыры. В sharplab.io все нормально выводится. Что не так?
Короче хз как это решать, похоже это баг. Особенно забавно, что для того чтобы сконвертировать флаги перечисления в список, на SO предлагают такую последовательность действий:
- enum перевести в строку
- при помощи Split разбить строку
- распарсить элементы массива в enum.
Мало того, что это дебилизм даже когда оно работает, но оно еще и не всегда работает, учитывая отрицательные числа.
![5lqJ81dbIY.jpg](https://2ch.life/pr/thumb/3097760/17184716238490s.jpg)
В enum можно переопределять значения:
> [Flags]
> public enum DaysOfWeek
> {
> Sunday = 1 << 0,
> Monday = 1 << 1,
> Tuesday = Monday,
> }
Здесь Tuesday и Monday равнозначные. И вот я хочу в комбобокс вывести список доступных итемов перечисления, используя для этого ObjectDataProvider. И какой же я список увижу?
> Sunday, Tuesday, Tuesday
потому что Monday это Tuesday, а Tuesday это Tuesday.
Вот какого хрена? Вот как эту залупу пофиксить? Ну выводи ты либо список оригинальных имен, либо не выводи дубликаты. Ну пиздец, ну сколько можно?
Ты сам себе проблему создаёшь специально а потом борешься с ней.
Если тебе позволяют что то сделать это не значит что нужно это пихать везде не включая голову
>Ты сам себе проблему создаёшь
Заходишь сюда
https://learn.microsoft.com/en-us/windows/win32/winmsg/window-styles
и видишь, что стили окна WinApi имеют совпадающие значения.
Если посмотришь примеры, где из этих стилей создают перечисление в шарпе, то увидишь, что там используются переопределения. А подход уровня "ну если это плохо работает, ну ты прост не используй это)))" — такой себе. Это просто откладывание проблемы на потом.
Это отлично работает и решает свои задачи. В коде это всё прекрасно работает и матчится.
С стилями и флагами ты уже заебал, если ты зелёный на вкате то не пизди что везде проблемы, а башкой и гуглом думай почему так сделано.
Каждый вкатун думает что умнее всех
Не, не выйдет.
Все варианты получения атрибута идут через указание строкового имени значения. А переводя элемент перечисления в строку, я получаю не оригинальное имя, а переопределенное.
![image.png](https://2ch.life/pr/thumb/3097760/17185696697140s.jpg)
Кому вообще в здравом уме понадобится использоваться Blazor Server ? Зачем отрисовывать страницу с большим пингом?
Почему микрософт пытается придумать свой велосипед? Блять придумали свою залупу в виде net core, одумались сделали net, начали какую то хуйню делать в Startup.cs одумались сделали нормальный с более понятной структурой Program.cs
В блазор сделали блять какие то режимы,@rendermode InteractiveAuto не работает без клиент. Спрашивается нахуя тебе клиент? Почему автоматический его не сбилдить? Делаем один проект помечаем компоненты @rendermode InteractiveAuto и все блять.
Я просто не понимаю смысла во всем этом.
Вот хочу я приложение сделать которое бы в бд писало строку, а потом мне показывало строки.
СОздаю проект Blazor Auto, я ожидаю что я буду писать код в клиенте обращаясь к классам и методам в сервере, а оно уже как то само http запросы будет делать и связыватся. Но хуй там плавал, создавай сам запросы, пиши web api и проче. Вопрос нахуй нужен тогда серверный проект?
Мне просто не понятна логика тех людей которые это сделали. Как они объясняют это вообще?
Я вот не знаю.
Может и нужно просто я не понимаю.
Это как с интерфейсами, я пока не понял зачем они вообще не использовал.
Ты никогда не найдёшь фриланс на WTF.
Способ 1. Я могу подписаться на PropertyChanged, а потом устроить что-то вроде if с проверкой имени изменяемого свойства. Проблема в том, что это событие будет возникать гораздо чаще, чем будет изменяться интересующее меня свойство. Плюс проверка стрингов как-то не очень эффективна на мой взгляд, особенно когда свойств будет несколько десятков.
Способ 2. Я могу создать подписку при помощи
BindingOperations.SetBinding, ну или обычным биндингом в XAML. Но вопрос в том, как эта привязка работает, и будет ли она более эффективной, чем вышеописанный способ 1? Потому что для привязки указывается путь к привязываемому свойству в виде той же строки, и это выглядит так, что она подписывается на все тот же Source.PropertyChanged и все так же при помощи Path определяет необходимое свойство.
Дык биндинг 2 внутри себя будет делать то же что и 1 если есть INPC иначе через TypeDescriptor будет следить через какую то там магию с подпиской на изменение свойства (с мемори ликом ведь это будет стронг привязка)
Насчет проверки стрингов - используя nameof ты получишь интернирование. Насчет [CallerMemberName] - возможно тоже (это нужно посмотреть что он там сгенерит)
Понял, спасибо
Так этих курсов полно. В этом вся и проблема, что они для начинающих в основном.
Единственное, что смотреть зашквар, это: Романа Сакутина и Гошу Дударя. И пусть тебя не смущает, что один критикует другого — оба прожженые инфоцыгане и советуют дичайшую ересь.
Можно с осторожностью смотреть XpucT, но лучше защититься от пси-лучей говнарства и секты WinForms. И при получении минимальных знаний незамедлительно дропнуть и не возвращаться.
Можно навернуть SimpleCode, а если не боишься умереть от кринжа и петросянских шуточек, что попробуй ExtremeCode. У каждого в начале много воды - можно скипнуть, и возможно установка вижуал студии 2015 уже не актуальна, но все остальное все еще имеет смысл. Там одним массивам уроков десять посвящено.
Ну или на торрентах искать туторы.
Simplecode просто лучший, посмотрел все видео у него и про c++ тоже. Жалко что нацистом оказался
> Типа пишешь метод как обычный синхронный, но при желании - берешь и запускаешь его как асинхронный
Task.Run разве не это делает?
![image.png](https://2ch.life/pr/thumb/3097760/17200118744500s.jpg)
Это блять че, это блять как?
https://antblazor.com/en-US/components/progress#API
MemoryMarshal.AsBytes
MemoryMarshal.Cast
Unsafe.As - собственно его MemoryMarshal и юзает под капотом
Task.Run - просто запускает метод в тредпуле и оборачивает его в таску, чтобы ты мог как с таской работать. Со всеми плюсами и минусами этого дела.
С горутинами - там, по сути - сделали свои софтверные потоки, которые поверх потоков ОС крутятся, и рантайм имеет возможность поместить ожидающий чего-то поток обратно в очередь и начать выполнять другую рутину. Т.е. примерно, как шарповские таски и работают или промисы в других языках. НО, при этом - ты метод свой писал абсолютно как синхронный, ты все еще можешь использовать его как синхронный, если надо, а если надо - можешь его как горутину запустить.
Репорт.
С SQL-запросом проблем никаких нет.
Как его переписать на EF? Сейчас не получается вытащить Id записи.
https://pastebin.com/fKKKvr2d
![image.png](https://2ch.life/pr/thumb/3097760/17206210169140s.jpg)
Мне нужно простенькое приложение под андройд написать. На чём писать его? На Мауи?
А ебала на скриншоте это что?
Я может тупой но твой SQL работать не должен банально потому что id нет в гроуп бай. Да и вообще какой id ты хочешь получить? Их же сколь угодно может быть при группировке по нейму
> Да и вообще какой id ты хочешь получить? Их же сколь угодно может быть при группировке по нейму
Тут мой косяк, копипастил из другого места, а sqlite прощает такие ошибки, попытался упростить называется.
По итогу, разобрался, виновник в лице sqlite был найден.
В очередной раз убеждаюсь какой же sqlite убогий, стандарт SQL поддерживает через одно место и позволяет писать так, как нельзя писать ни в одной другой нормальной реляционке.
Там 2 таблицы, связь один ко многим, поэтому имена могут повторяться и мне нужно было вытащить айдишник, имя и сумму по данному имени.
Расследование (полная схема + тестовые данные):
https://pastebin.com/f77ZEx00
> Я может тупой но твой SQL работать не должен банально потому что id нет в гроуп бай
Не должен, но sqlite плюёт на правила:3
В стандарте прям так и написано, что в этом случае обязательно должна возникнуть ошибка?
Понял, спс.
![](img/mob.gif)
https://2ch.hk/pr/res/3218883.html (
![](img/mob.gif)
https://2ch.hk/pr/res/3218883.html (
![](img/mob.gif)
https://2ch.hk/pr/res/3218883.html (
![](img/mob.gif)
https://2ch.hk/pr/res/3218883.html (
![](img/mob.gif)
перекот, бо тред стух и мало кто пишет
>>218884
ОТМЕНА
https://2ch.hk/pr/res/3218902.html (
![](img/mob.gif)
https://2ch.hk/pr/res/3218902.html (
![](img/mob.gif)
https://2ch.hk/pr/res/3218902.html (
![](img/mob.gif)
Легитимный. Прошлый не попал в каталог так как видимо я не написал /csharp/
Или я хуй знает почему он не попал в каталог
Корчои удалите тот который не правельный
Это копия, сохраненная 12 июля в 00:33.
Скачать тред: только с превью, с превью и прикрепленными файлами.
Второй вариант может долго скачиваться. Файлы будут только в живых или недавно утонувших тредах. Подробнее
Если вам полезен архив М.Двача, пожертвуйте на оплату сервера.