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
Прошлый тред: >>3097760 (OP)
Можно. Инструментов очень много: MonoGame, Duality, Stride, Godot. Выбирай на свой вкус и под свои задачи.
Лучше попробовать самому написать игровой движок и 3Д рисовалку в реальном времени. Пусть даже на ЦПУ. Не понимая базы, ты будешь макакой-кнопкодавом.
А там ничего сложного нет, геометрия за 9 класс.
project.DAL;
public abstract class Entity
{
int Id {get; set}
}
project.BAL
public abstract class Model<T> where T Entity
{
public int Id {get; set;}
public Model(T entity)
{
Id = entity.Id;
}
public abstract Entity GetEntity();
}
Но не покидает ощущение, что я написал хуйню.
> project.BAL
> public abstract class Model<T> where T Entity
У тебя из слоя логики ссылка на слой бд. Такого быть не должно.
Заменяем все это на "это суть модели" и "такого быт не должно" сразу исчезает.
А он нормально работает с абстракциями? У меня есть таблица проектов, каждый проект содержит список блоков, (точнее даже список сопоставлений блоков и проектов, где помимо блока и проекта есть еще позиция блока в проекте, но это уже мелочь) где блок абстрактный класс, у которого у меня на данный момент десяток разных наследников, каждый со своими полями. Как это все перенести в модели и обратно я не представляю.
Изначально такой зависимости не планировалось ну, кроме хранения Id, ибо без него хз как обновлять сущности, но начав реализовывать круды я понял, что мне придется писать тонны бойлерплейта, проверять конкретный тип блока, чтобы правильно смаппить его, держать в голове, что при добавлении блока необходио добавить новый switch case. В итоге данное решение показалось надежнее
Почитай как он работает а потом уже пытайся задавать вопросы.
А наследование вместо имплементации - зло почти всегда
> Изначально такой зависимости не планировалось
По-хорошему, у тебя проект с логикой не должен ни от чего зависеть, нугеты не считаются. А вот проект с бд должен зависеть от логики.
Бизнес логика должна знать подробности о том как происходит хранение?
> А наследование вместо имплементации - зло почти всегда
Не понял, что ты имеешь в виду. Как в моем случае можно реализовать по другому?
Интерфейсы. Я почитал что ты пишешь и звучит что ты пытаешься сделать не как надо а так что бы кнопки тыкать поменьше (что обычно автоматизируется/убирается либами)
Нет. Домен не зависит от способа хранения данных. Это может быть как реляционная бд, так и текстовые или xml файлы.
Речь о наследовании которое чаще зло чем польза. Что касается моделей смысла в наследовании точно никогда нет
Ну заменю я базовый класс в моделях на интерфейс, что изменится то? Все также придется тип наследника, писать логику для работы с ним
Наш российский UNIGINE тоже поддерживает C# и там аналог люмен завезли раньше, чем в Unreal Engine. Сперва анриал хотел выкупить его, но потом сделал свой. True story
Какой фреймворк взять для разработки небольшого кросплатформенного GUI под (Linux/Windows)?
А именно Ubuntu/Win10-11.
MAUI подойдет?
Там столько всяких вриантов, абравиатур, я уже запутался..
ну раз линукс, то мауи идет лесом. Мауи это попытка замаринцам дать десктоп, причем попытка убогая ибо линукс мимо
А потом выбор прост.
Eto Forms для любителей формошлепства
Avalonia для любителей WPF
то есть для любителей Lookless без дрочева с ручным рисованием.
сам конечно хамл не люблю, но походив по базару...
>А потом выбор прост.
>Eto Forms для любителей формошлепства
>Avalonia для любителей WPF
спасибо большое няша
а про GtkSharp ничего не знаешь? GTK же как и QT кросплатформенный
Пока в вилларибо разбираются во всех этих левых биндингах (и проблемами чужеродного движка) - в виллабаджоуже сделали на ето.формс или авалонии и получили денежку
(хоть сам ето не люблю, но факт есть факт)
еще раз спасибо няша.
нихуя не знаю, ни сишарп, ни авалонию, но в понедельник вечером должен сдать "проект".
ну и там правда все реально просто
так то я на линусошиз, байтоеб, пишу на крестах
в рот я эту винду, но хули на работе заставили
SQL query.
Я пару раз юзал именно query-синтаксис пока с Linq2Db работал. С ним сложные джойны и группировки пишутся быстрее и выглядят читаеемее, чем через чейнинг методов.
Плюс с помощью него достаточно удобно всякие не очень сложные парсеры с помощью либы Sprache описывать https://github.com/sprache/Sprache?tab=readme-ov-file
Использую sql + dapper.
Linq и прочий рак уровня dynamic придумали менеджеры, чтобы впарить лохам новую версию вижуал студии. Когда-то были времена, когда студия стоила денег, а сишарп был модной популярной технологией.
Зависит.
Когда удобнее написать через квери - квери.
Когда удобнее написать через экспрешн - экспрешн.
Когда надо чтобы быстро - голый скуль.
Ну. Типа. Дополнение.
Вот мне надо первый элемент найти по ид найти.
Экспрешном - это будет одна строчка. Квери - это будет дохуя строчек. Берем экспрешин.
Надо написать какой-то сложный жоин с группировкой и прочими хуйнями. Экспрешном - это превратится в какую-то кашу ебаную. А квери - ок смотрится, еще и не надо как еблан постоянно инклудить все. Берем квери.
О. А теперь нам надо какой-то массовый апдейт сделать. Допустим, при запуске приложения - всем пользователям выставить статус оффлайн, ведь мы этот статус в БД держим зачем-то. Пользователей дохуя. Обычный скуль - за 0,000000000000000000000001мс выполнится, условно, черзе еф - ты будешь ждать запуска приложения 1000000000000000000 лет, пока все переберешь, пока всем переставишь статус. Так что берем и дергаем обычный скуль.
Можно ли как-то собрать библиотеку, чтобы она была одним .dll и в себя все зависимости включала?
Распишу в чем проблема.
Вот есть у меня проект. Модульный. В базовой сборке - описаны всякие интерфейсы того как сделать свой модуль, который бы мог подключиться к основному ядру приложения, и начать работать. Есть сборка которая реализует ядро. Ядро лезет в папку {installDir}/modules и ищет dll с подмодулями, загружает их и погнали.
Все так работало.
Но меня, смущает, что папка в которую кладутся модули выглядит как пиздец, ведь после сборки библиотеки модуля - там лежат все .dll с зависимостями, ресурсами. Очень сильно глаз режет. Хочется чтобы было просто CompanyName.Module1.dll, ComplayName.Module2.dll. Плюс - нельзя просто сказать пользователю - удали эту .dll и подкинь вот эту.
В древние времена на плюсах делал такое и на выходе был один dll на модуль. Уже не помню как эту магию делал. Давно было. А как на шарпах сейчас так же сделать - чет не представляю. Для библоитек не реботает --single-file
Даже если модуль зависит только от базовой сборки где интерфейсы лежат - на выходе имеем 2 .dll с базовым проектом и модулем.
>This function fails when it is blocked by UIPI. Note that neither GetLastError nor the return value will indicate the failure was caused by UIPI blocking.
А в чем подробность, если мне просто возвращается код?
Не тот фрагмент процитировал
>The function returns the number of events that it successfully inserted into the keyboard or mouse input stream. If the function returns zero, the input was already blocked by another thread. To get extended error information, call GetLastError.
Расскажи поподробнее как твоё ничего.
На нугет орг для проверки уязвимых пакетов ходит, отключается.
Сам с такой парашей столкнулся когда внутри контура сборку настраивал
![image.png](https://2ch.life/pr/thumb/3218902/17209817709910s.jpg)
Фотку когда то делал для других согильдийцев
Алсо, почему-то все найденные мной мапперы не утруждают себя поддержкой netstandart 2.0, так что приходится пользоваться протухшими версиями.
Фреймворк похоронен сто раз, те кто его ещё юзают сами ставят подпись в договоре с дьяволом
Так не о фреймворке речь, а о UWP. Он, увы, поддерживает максимум .net core 3.1 и netstandart 2.0.
UWP похоронен сто раз, те кто его ещё юзают сами ставят подпись в договоре с дьяволом
Проблема: проект blazor каким-то образом ебически кеширует страницы на клиенте. У меня был не дописан контроллер на сервере, вернулась 404 страница вместо джейсона и блейзор выдал ошибку и продолжает её выдавать даже после того как я пофиксил контроллер.
- В постмане все нормально возвращается по тому же адресу
- Очистка кэша/сессии/данных/ctrl+f5 браузера не помогает, зато помогает анонимное окно, только в нем не работает дебаг, либо фаерфокс вместо браузера в котором тоже на работает нормально дебаг
- Полная очистка проекта/удаление obj/bin, ничего не дает
- Коментирование UseHttpCacheHeaders/UseResponseCaching/config.CacheProfiles ничего не дает
- Попытка пробить експирацию кэша вслепую (увеличил системное время на неделю вперед) тоже ничего не дает
Где-то пол года назад я уже здесь писал и тогда как-то сам и пофиксил и уже забыл чё делал, а сейчас чето головой об стену бьюсь.
>>21698
Все отбой.
1) Почистил уже конкретно на запросе во вкладке network, теперь прошло нормально.
2) У меня в проекте оказывается подключен Marvin.Cache который дает такую шляпу, только опять же по какой-то причине мне не выдает этот пакет в нугете. Нужно его будет когда-то его доковырять вероятно никогда
Хочу разделить конфиг сущностей по файлам, чтобы не лепить портянку на 1к строк в одном файле.
![изображение.png](https://2ch.life/pr/thumb/3218902/17211249714900s.jpg)
Точку останова поставь и по шагам посмотри что творится с массивом, куда там черточки пихаются.
Кароч понятно. Для for я беру длину listChar. Длина постоянно увеличивается из-за неправильной логики добавления чёрточек. Ну пиздец
![изображение.png](https://2ch.life/pr/thumb/3218902/17211277208720s.jpg)
Я знаю, но у меня немного другая ситуация. Этот пакет мне не поможет. OwnsOne добавляет имя класса в имя колонки.
что лучше для десктопа xamarin или winforms?
перекатываюсь с плюсов в шарпы, объясните малютке
Какая разница?
Пробую новый инструмент, но документация у linq2db ужасная. Сайт фиг знает сколько лет не обновляли.
>>21937
Проблема с конфигурацией оказалась лишь началом.
Есть ли какой-то автомаппинг колонок бд из snake_case в CamelCase для ДТО-шек? Аля DefaultTypeMap.MatchNamesWithUnderscores = true из даппера.
Засорять запрос "as НазваниеКамелКасе" не хочется.
https://pastebin.com/Zkm7GxZT
>У linq2db есть аналог ApplyConfigurationsFromAssembly и IEntityTypeConfiguration<T> из EF?
>Хочу разделить конфиг сущностей по файлам, чтобы не лепить портянку на 1к строк в одном файле.
>>22503
>кодил я вот такой код, как на картинке. Нужен был, чтобы в IEntityTypeConfiguration имена колонкам задавать с нижнем подчёркиванием, но это не суть.
>>22637
>Проблема с конфигурацией оказалась лишь началом.
>Есть ли какой-то автомаппинг колонок бд из snake_case в CamelCase для ДТО-шек? Аля
А, казалось бы, возьми EF и не мучайся. Но нет, пацаны же сказли, что EF тормозной и сложный, а даппер простой и быстрый - буду страдать.
Ну мб людям надо.
Как то нужно было загрузить в bd очень дохуя инфы, и писал я прилку на заказ которая это сделает.
И вот EF работал раз в 10 медленнее чем даппер, и вот получалось 3 дня и 30 дней загрузки. Был резон юзать даппер.
А в случае дрочбы на нано секунды то да это нахуй.
>И вот EF работал раз в 10 медленнее чем даппер, и вот получалось 3 дня и 30 дней загрузки. Был резон юзать даппер.
1) В том и прикоол, что когда надо быстро-здесь-и-сейчас, берут даппер и не страдают дрочевом с паммингом, конфигурациями и т.д. потому что в какой-то момент всегда получается, что ты ради "удобства", просто пишешь свой аналог EF поверх даппера.
2) EF сейчас уже настолько наоптимизировали, что большинство случаев когда "медленно", обычно означает - хуевое проектирование
3) EF так же умеет во встройки, чистый sql и вот это все при необходимости, когда надо грязно и быстро.
4) Для особых ценителей, можно вообще использовать их одновременно, чтобы там где надо "удобно" юзать ef, а где "быстро" - даппер.
Еф уже давно не только еф но и база которую расширяют специфичными для конкретных субд аддонами оставляя еф как прослойку которая знает как классы мапятся на схему бд.
Из последнего что юзал это аддон на инсерт ... он конфликт ду ... и булк инсерт когда нужно было залить пару десятков кк записей.
Но юзая подобные плагины нужно читать доку т.к. большая их часть работает в обход чендж детектора (что очевидно).
Я лично топлю за еф в первую очередь потому что он выступает единой точкой правды (классы+конфиги) и даёт удобные миграции из коробки.
А за счёт чендж детектора можно иногда очень даже разгрузить бд/не писать бойлерплейт.
Если даже есть то что ну никак не получается решить кодом то всегда можно из того же дбконтекста вытащить коннект и юзнуть даппер
Дополню тебя что в дебаге стоит всегда логать запросы что бы не жаловаться потом что говна в жопу подкинули, ровно как и чекать миграции
На новой работе досталось в наследство 30-40 микросервисов которые как то нахуеверчены на даппере и запросы там собираются склейкой строк (пиздец). Каждый такой запрос получается уникальным и оседает в кэше даппера. Смотришь на дамп памяти сервиса а там 800мб чистого SQL текстом в куче
Ещё хз с какой версии ефа появилась возможность ресетать дбконтекст и юзать его почти как синглтон а не уов
>ровно как и чекать миграции
Ага, главное руками в них не лезть.
Часто попадаются любители, когда в миграции что-то не так, просто нахуевертить руками исправления в миграции, т.к. мозгов сделать это правильно через код не хватает.
Всегда на ревью такую хуйню заворачиваю, пока мне не докажут невозможность сделать миграцию нормально без ручных правок. Никто еще не доказал.
у меня даппер почему то пропускал id некоторый.
Пример, добавляю новые записи, их 1кк, в бд последняя запись с id 1 200 000. Но записей всего 1кк как и должно быть.
Ебенит типо 1-200 потом 280-500 пропустил 80 id и пошёл дальше, и все время одни и теже пропускал. Хуй знает почему.
Хз. Я порой добавляю всякие грант пермишшенс и делит данных.
Пару раз патчил что бы вместо ренейма был делит+адд.
В целом соглашусь что править их плохо, а тем более мержить, шанс что потом другой разраб набьёт ебало когда снапшот пойдёт в рассинхрон с миграциями слишком велик
>>22959
Логи включай, магии не существует
>Я порой добавляю всякие грант пермишшенс и делит данных.
Это все можно провернуть через конфигурацию. И даже в суперсложном случае, где надо задействовать, что-то, чего EF не умеет и прописать это через чистый SQL, это проще делать через конфигурацию, чем встраивать в автогенеренный файл.
>>22964
>и делит данных
Если речь идет о сидированных данных, и это изначально делать нормально, через .HasData, то и удаляется это тоже таким же способом. Если же речь об удалении обычных данных, то это не область ответственности миграций.
>>22964
>Пару раз патчил что бы вместо ренейма был делит+адд.
Такое можно делать через две миграции подряд. Сначала в конфигурации лепится на измененный объект игнор, генерится миграция на удаление. Потом игнор убирается и генерится вторая миграция.
Плюс такого подхода, что все миграции можно в любой момент снести и сгенерить одну новую единую (например при переходе на новую БД) и она будет содержать конечный результат идентичный старому набору миграций, без всяких ручных правок.
спасибо анон. добавлю флаг нокеш.
Как тут смапить к GetTransportationRequestResponse?
Сука ебаная. А теперь я обнаружил, что тут есть вот такой баг, который с 2021 не пофиксили https://github.com/DapperLib/Dapper/issues/1693
ну почему с 21го
проблема где SplitOn равен нулл и поэтому остальные колонки не собираются в объект - она куда древнее
https://github.com/DapperLib/Dapper/issues/266
потому что задумка такая "если первое значение нулл, значит вероятно весь объект нулл и нечего его конструировать"
А вот решения "ты мне тут не гадай, а собери объект" нету. Есть пуллреквест на "а давай делить по полю которого нет в модели", но толку то.
Да, проще.
Не нужно учить "еще один метаязык" в котором хрен поймешь как выразить нужное и при этом чтобы оно было эффективным.
Про стартап тайм вообще молчу. Он там майнит что ли? Ну да кодоген немного исправил ситуацию, но там свои правила.
> Не нужно учить "еще один метаязык" в котором хрен поймешь как выразить нужное и при этом чтобы оно было эффективным.
Ну как не нужно, нужно учить sql. Я вот использую ef core уже лет эдак 5, из sql зная только select from и where.
рад за тебя. но не все пишут бложики. да сайтики на 3.5 рпс (где с не секунды, а сутки)
В целом легко обходится, но когда-нибудь мне это боком вылезет
Всё можно в монгу сложить без вот этой ебли с маппингом.
Нет, не уйду.
В 90% использование рбд -- это каргокульт. Потому что так заведено. Деды писали хранимки, и ты пиши.
Так иди, я тебя не держу.
Это ж про сишарп тред, а не про базы данных. Можешь идти туда выражать свою любовь к ключам и таблицам.
Ура! Я нашёл решение проблемы.
Не видел такого.
Вернее видел, но у мауи. Comet называется.
Я конечно одобряю, но все же это все еще очень очень очень сыро.
Даже примеров толковых нет
ну и конечно ограниченность шарпа мешает
Сама ощибка: Npgsql.PostgresException (0x80004005): 42601: syntax error at or near "$2".
Что я делаю не так? Запрос рабочий.
А ты вообще уверен что эта часть в запросе у постгреса параметризуремая? Что то мне говорит что нет.
Та же ситуация когда в запросе нужно заменять in на any
Ты зачем продолжаешь гнуть линию? Я тебе же сказал что не каждая часть запроса параметризируется. Иди в доку, а не доказывай свои догадки
Именно. Я же привел пример с ин и эни
А можно просто еф взять...
Спасибо, что наставили на путь истинный.
Разумеется, я знаю, что класс может унаследовать один класс и реализовать множество интерфейсов, но ведь если мы разрешим множественное наследование, то получится, что абстрактный класс содержит весь функционал интерфейса:
- Реализация объявленных методов
- Реализация методов по умолчанию (с c#8.0+)
- Реализация свойств
Я встречал разные моменты по типу:
>Интерфейсы формируют интерфейс взаимодействия у классов.
Так ведь при помощи наследования классов наследуются публичные поля и методы, тем самым тоже наследуется интерфейс взаимодействия классов.
Я глубоко не вникал, но у меня есть подозрение, что они как-то по разному в промежуточном коде выглядят, неспроста же у интерфейсов конструктов нет. Но я этот код в глаза не видел, к сожалению.
В общем, подскажите, пожалуйста, зачем нужны интерфейсы и где они справляются со своей задачей лучше, чем абстрактные классы
Интерфейсы больше про семантику, чем про технику. Это как спрашивать, зачем нужны while/for/else/switch, если есть goto.
> Что они могут делать такого, чего не может абстрактный класс
В шарпе - нет множественного наследования.
В твоем коде - тебе может быть интересно, что у класса должен быть метод с такой сигнатурой, а из какой он иерархии - тебе до пизды.
Сверху, довольно долго интерфейс в шарпе - не содержал логики и было заебись.
> , но ведь если мы разрешим множественное наследование, то получится
Проблема ромба получается. Два класса - наследуются от одного базового, потом третий класс - от обоих наследуется - пизда, нахуй, треш-угар-садомия, трудноуловимые баги и прочий ужас.
> что абстрактный класс содержит весь функционал интерфейса
Да. В плюсах так и делают.
Проблема абстрактного класса как раз в том, что в нем может быть сокрыто дохуя и больше логики, дополнительно - уже сказал, проблема ромба:
class A { abstract void foo();}
class B : A { override void foo() => Console.WriteLine("B")}
class C : A { override void foo() => Console.WriteLine("C")}
class D : B, C { }
Я создал инстанс D - что должно вывестись при вызове метода foo()? Хуй его знает на самом деле. А если я скастю к B? А к C? А к А? Короче хуйня выходит в любом случае.
Вот чтобы о такой хуйне не думать - все нормальные языки - запретили эту хуйню с множественным наследованием.
НО нам все еще нужен механизм, который позволит описать как куски программы могут ОБЩАТЬСЯ друг с другом на уровне четкого контракта.
Страшно — вырубай.
Я понимаю проблему ромба, но ведь её порождают и интерфейсы в c#8.0+ где есть реализация по умолчанию.
Если откреститься от реализации в интерфейсах, то получается что абстрактные классы имеют реализацию, но были лишены множественного наследования, чтобы эта реализация не сломалась?
Вот есть список обьектов, их последовательность обязательно нужно сохранить
Но когда добавляю через AddAsync каждый перебором, а потом SaveChanges жму - они добавляются в рандомном порядке
Вижу решение жать после каждого добавления сохранение изменений, но разве нет другого варианта?
(Ну еще нумерацию внутри обьекта сделать, но тоже гемор)
Без практики, наверное, такое сложно будет осмыслить. Но дело в том, что интуитивно не очевидно, что и где использовать.
https://www.youtube.com/watch?v=fu13d1V73K4
Например в этом видео автор создаёт интерфейс IEngine. Я бы на интуитивном уровне подумал, что тут нужен абстрактный класс, а не интерфейс, потому что до этого в уроках было что-то типа IMoveable и я подумал, что интерфейсы типа для действий нужны, но тут мои додумки ломают
Если ты про id - то что тебе мешает прямо при добавлении его присваивать?
Автоинкрементные столбцы по факту ничего тебе не обещают кроме того что ты не получишь две одинаковых цифры. Те же сиквенсы игнорируют транзакции и соответственно роллбэк.
Если тебе нужно сортировать столбцы то НИКОГДА не делай это по иду если он автоинкрементный. Из последних приколов которые позволяют генерировать псевдослучайные идентификаторы по которым можно сортировать по времени это uuid v7
В качестве айдишника у меня Guid просто
Буду похоже дополнительно номер порядковый держать для обьекта, а потом сортировать на выходе по нему
Интерфейс просто более гибкий вариант. Создавая абстрактный класс ты лишаешься возможности легко вписать уже существующую логику в новую. К примеру создаешь ты игру, условную веселую ферму, создал иерархию классов животных - Animal -> Horse. А в новой версии захотел добавить транспорт. Если Engine будет абстрактным классом, то его никак не добавить к лошади, а вот если он будет интерфейсом, то получится без проблем его реализовать - Horse : Animal, IEngine.
Вообще, тут стоит руководствоваться следующими соображениями - если есть много логики, которая будет повторятся, то надо вынести ее в абстрактный класс, если же такой логики будет минимум и нужно обеспечить общий функционал, то лучше делать интерфейс.
Нахер они добавили реализацию в интерфейсы. Бред какой-то. Может хотят убить абстрактные классы, потому что сейчас в них вообще нет никакого смысла.
Цель мутная и больше для тех кто пишет костяк дотнета, остальным фича не упала
Ты не понял про что он говорит
Чтобы можно было добавить задним числом в интерфейс новый метод, не заставляя всех, кто реализует этот интерфейс, дописывать тонны кода.
Бессмысленная хуйня, учитывая, что без доступа к приватным полям едва ли получится реализовать что-то осмысленное. Лучше бы тогда добавили какое-нибудь ключевое слово для методов, чтобы этот метод можно было не реализовывать, а при вызове он бы кидал исключение not implemented.
К слову метод можно также добавить написав обычный экстеншн.
Потому что бывают случаи, когда какой-то метод тривиален и у всех будет одинаково реализован.
Если мы опять же вводим абстрактный класс, то получается, что все должны от него наследоваться, а в контексте того что наследоваться в шарпе можно только от одного родителя - усложнение иерархии, которое нахуй не нужно-то.
До этого приходилось костылять сбоку методы расширения для таких вот целей, но это костыль и вообще, когда ты обязан для работы с каким-то интерфейсом постоянно что-то из расширений тянуть - почему это не сразу в интерфейсе.
Ну типа, ну лол. Вот у тебя какой-то класс логгера.
Есть метод Log, который принимает уровень, паттерн и прочее. Очевидно, что сделает каждый - напишет по методу расширения: LogError, LogWarning, etc. Но с расширениями - теперь надо будет еще какой-нибудь using Suka.Pizda.Zalupa.Logger.Extension не забывать подключать постоянно как еблан, или выносить его в глобальные юзинги, в любом случае - кал выходил. А так - оно сразу в интерфейсе просто уменьшает число аргументов метода Log.
Абстрактные классы никто убивать не хочет и не собирается. Они все так же нужны. Какой-нибудь фреймворк ты без этого - хуй напишешь нормально.
Да ничего умного там нет. Это просто отдельный тип списков, у которого свои особенности, например позволяют получать или извлекать данные из других потоков. С обычными списками такое не прокатит, потому что если так совпадет, что два потока одновременно обратятся к обычному списку, то выскочит ошибка.
Есть дополнительные специфические особенности. Например очередь Queue устроена таким образом, что элемент добавляется только в конец списка, а извлекаться может только с начала. Получается типичная схема очереди, типа "кто первый подошел, того первым и обслужили". С обычными списками такой подход геморно реализовать.
По факту, интерфейс - это просто вариант абстрактного класса.
все там легко осмысляется
женщина и мужчина наследники класса человек. и в класс человеков можно вынести что есть руки ноги, дышать, спать. То есть абстрактный класс дает и общий контракт и общую реализацию.
А вот интерфейс семантически подчеркивает какой то аспект. Например IМожетДышать или IСонька
Тут аспект на конкретно этом, и как бы уже неважно человек там или камень. Таким образом может быть куча интерфейсов, каждый из которых описывает свой аспект.
Конечно интерфейс может описать всё и использоваться вместо абстрактного класса.
Тут ведь сколько человеков, столько и мнений
одни скажут что "ууу нарушается буковка I в SOLID".
другие скажут - "это контракт и ниипет, идите лесом".
Так что будет тебя склонять в сторону использования только интерфейсов пока не понадобится общая реализация, на которую интерфейс просто не способен.
У тебя неправильный вопрос. Правильный - зачем нужны абстрактные классы, когда есть интерфейсы. Ответ - нахуй не нужны, это древнее легаси из темных времен, когда все дрочили на инкапсуляцию наследование полиморфизм, хуярили абстрактные фабрики и мартин высирал свои книжки по кд. Сейчас используют анемик сервисы, никто не пишет развесистые иерархии наследования.
>но ведь если мы разрешим множественное наследование,
то код утонет в говне, в общем для этого и сделали интерфейсы чтобы одно изменение какого то родителя не ломало нахуй всё и ты это говно потом лопатой дня три разгребал.
>Я никак не могу выкупить, зачем нужны интерфейсы? Что они могут делать такого, чего не может абстрактный класс?
контракт, чтобы классы реализовывали одинаковое поведение и не были ограничены одним классом как в наследовании.
> зачем нужны интерфейсы и где они справляются со своей задачей лучше, чем абстрактные классы
большая гибкость чем у абстракций, интерфейсов можно нацеплять много.
>>26931
>Нахер они добавили реализацию в интерфейсы.
чтоб бойлерплейты не писать
>женщина и мужчина наследники класса человек. и в класс человеков можно вынести что есть руки ноги, дышать, спать. То есть абстрактный класс дает и общий контракт и общую реализацию.
Я как в 2000 попал. Тогда и давали все эти убогие примеры типа класс человек, наследники студент, препод и методы пойти на пару и пойти в столовую.
Не надо так писать, все уже давно убедились в том, что это нормально не работает.
Надо делать классы-данные, Plain old CLR object с данными и без логики, и классы-сервисы с логикой, но без состояния.
Тогда никакое наследование не нужно, абстрактные классы тоже не нужны, общий код для двух реализаций одного интерфейса просто выносится в отдельный класс-сервис и подключается в виде зависимости.
Такой код проще менять и тестировать.
Вот этот >>27330 всё правильно написал.
ты щас пытаешься породить древний срачь adm vs rdm.
на адм у тебя как сопля размазана везде, для небольшого проекта это плюс так как каждое говно лежит в своей урне, но как только проект растёт растут и сопли и бегать собирать их по огромной кодовой базе занятие для мазохистов
на рдм говне все это лежит в одной куче которую осмысляешь как буддисты дзен, но хотя бы в одном месте.
>Я как в 2000 попал
этим паттернам анемик и рич уже тоже лет по 15
да хоть в какие попадай. Концепция ООП старше тебя и за эти годы в общем то осталась какой и была.
И если у тебя что то там не работает - ну значит у тебя лапки
А свое неумение использовать парадигмы на всех проецировать не стоит. Смекаешь?
>Надо делать классы-данные, Plain old CLR object с данными и без логики, и классы-сервисы с логикой, но без состояния.
яскозал? Выбор того или иного - ЗАВИСИТ!!!
Видимо ты всю жизнь писал один продукт и жизни за его пределами не видел.
Студент, ты учишься по устаревшим учебникам. В 2024 году рич ооп - это говно без задач, годится только для древнего легаси на винформсах.
в любом большом корпоративном говне будет рич, в мелком когда как.
ЯСКОЗАЛ? ок. ниосилятор пропагандирует свое видение мира (хотя мира конечно же никто не видел)
>да хоть в какие попадай. Концепция ООП старше тебя и за эти годы в общем то осталась какой и была.
Это не так.
>И если у тебя что то там не работает - ну значит у тебя лапки
>А свое неумение использовать парадигмы на всех проецировать не стоит. Смекаешь?
Чем сложнее граф зависимостей -- тем сложнее что-то менять. А менять что-то приходится постоянно.
Для этого придумали IOC, чтобы зависимости были деревом, а не хуй пойми какой мешаниной. Как следствие, в листьях у тебя должно быть что-то максимально тупое с минимумом логики и без каких-то других зависимостей. ПОКО в это прекрасно ложатся.
>>Надо делать классы-данные, Plain old CLR object с данными и без логики, и классы-сервисы с логикой, но без состояния.
>яскозал? Выбор того или иного - ЗАВИСИТ!!!
Ну дали тебе екстеншен методы, можешь ими пользоваться, разрешаю.
>Видимо ты всю жизнь писал один продукт и жизни за его пределами не видел.
Сейчас одиннадцатый пишу. Некоторые, в которые глубоко не залезал, я считать не стал. Посчитал только те, в которых я оказал значительное влияние на дизайн кода.
Я старый, мне под сорокет уже. Я много чего видел, и в том числе адский говнокодище, который получается, если не устанавливать себе строгие ограничения в стиле.
Да не надо винформс учить, им никто не пользуется. Максимум - обертки для редактирования конфигурации основного приложения.
Учи АСП.НЕТ.
вообще то поко могут содержать логику вне анемичной модели.
В моей хохлосрани (Киев) одна вакансия и та фейк, и шо? Ты живешь в свободной стране, тебя никто не остановит на блокпосту и не упакует потужно в бусик. Просто берешь и переезжаешь туда, где вакансий не три, а триста.
Винформс - это тупик, ими можно заниматься, когда тебе за сорок, айти доебало в принципе и уже похуй, что и на чем писать. Вкатывайся в клауды, аспнеткоре серверлес кап теорема вот это все, а не пытайся ковырять окаменевший кал на винформс.
Ну так целься сразу на удалёнку в какую-нибудь Московскую/Питерскую контору. Тем более ты в том же UTC+3, что и Москва.
Винформы, да и вообще десктоп разработка (WPF, Авалония) это смерть, гроб, кладбище для 50-тилетних скуфов, просиживающих штаны в госконторах и НИИ-ах.
про десктоп не совсем верно. Просто он нужен для написания чего то внутреннего. И это далеко не только госконторы и нии. И далеко не всегда древний фреймворк.
но изучать его новичку нет смысла, да.
>Это не так.
ты про фишки в виде автореализации в интерфейсах которые по факту причуда одного языка?
>в листьях у тебя должно быть что-то максимально тупое с минимумом логики
Кому должно? С IoC действительно проще (удобный паттерн), но описанной тобой проблемы сложности нет. Проблема сложности это когда ты напихиваешь кучу всего и нарушаешь DRY, KISS, SOLID и еще кучу аббревиатур. Только причем тут вообще ооп. ООП это про базовое структурирование кода - классы, методы, взаимодействие и прочее, а детали "где как насрать" уже на тебе
>Ну дали тебе екстеншен методы, можешь ими пользоваться, разрешаю.
спасибо за разрешение. только вот ектеншен методы несколько другое. В частности интерфейс ничего про них не знает. А значит они и не являются переопределяемой реализацией (что базово для ооп). Так что эти методы хороши, но по факту DSL, а не ООП
>Сейчас одиннадцатый пишу.
11 проект одного типа? ну такое себе. И это только на шарпе? ну тоже такое себе.
Я изучал с десяток языков (а в каждом свои парадигмы) и под что только не писал (причем всегда у меня за правило "не тащить в чужой монастырь свои привычки". К чему это я? - не быть категоричным "я знаю все"
>если не устанавливать себе строгие ограничения в стиле.
для этого и придумали паттерны (не те, которые GoF), а вообще про дизайн...чтобы структурировать. Только причем тут "нам нужен абстрактный класс или интерфейс" - выбор этого определяется правилом "я конечно люблю интерфейсы, но с ними получается лютое говно в данной задаче"
>но изучать его новичку нет смысла, да.
Считаю что WinForm или типа Qt - самое лучшее для вката. Писать десктопные проги намного интереснее чем веб. И главное все наглядно и понятно, в отличие от веб-фреймов где под капотом что то делается и выдается результат. По мне так можно потренить на десктопе хотя бы первый месяц, может затянуть кстати.
>> про десктоп не совсем верно. Просто он нужен для написания чего то внутреннего.
В нескольких местах, где работал, как раз занимался тем, что внутренние штуки для автоматизации бизнеса переделывал с десктопных апп на современные, модные, молодежные веб-приложения. Новые десктопные приложения там запиливать не хотели. Так что скажу так, есть существенная тенденция к отмиранию десктопных приложений.
Из того что знаю, та область, где десктопные аппы плотно сидят и умирать не собираются - это различный внутренний инженерный софт. Но ради него, да, формы или WPF учить явно не стоит. Там банально для трудоустройства будут скорее всего будут требовать вышку. Причем скорее всего не айтишную, а инженерную, по профилю работы компании или смежную с ней.
задрочил по десять раз метанит, рихтера, sql и возник вопрос чё дальше то учить
в мок собесах спрашивают исключительно синтаксис и базу по .net, в вакансиях то просто "знание C# и SQL" то сверху HTML JS TS ASP.NET CORE - мягко говоря дохуя информации
пока для себя наметил только выучить SOLID, EF Core, поковырять git
в общем анончики подскажите в каком направлении двигаться а то нихуя нет представления даже какие пет проекты можно с текущими знаниями делать
> HTML JS TS ASP.NET CORE
Вот это и учи, плюс реакт. Тайпскрипт можно пока пропустить. Еще нужно знать докер, CI/CD, гит обязательно. Базовые навыки пердолинга консольки не помешают.
Не, нихуя. Веб интереснее хотя бы потому, что есть миллион готовых примеров, интересных библиотек с разными контролами, и в целом очень легко найти информацию по любому вопросу. Плюс css куда гибче и выразительнее xaml. До сих пор помню эти лесницы из десятков вложенностей, с необходимостью повторять имя родителя при задании свойства.
ты вакуху то смотри, если там фулстек то объем ебейший
Стоит ли смотреть?
ну мужик наглядно пересказывает учебник, если тебе проще смотреть и слушать чем читать, смотри и слушай.
считай это аудикнигой с примерами
но почему?...
Чел. Подумой! Это же целых 9 часов! ДЕВЯТЬ! За эти 9 часов - ты можешь! Ты можешь... Хуй знает что ты можешь.
По сакутину и его материалам. Там все оч поверхностно. Типа новичку - ок. Кто хотя бы 100к строк написал - там вода и не очень смешные шутки.
Короче. Вот тебе задание. Берешь VisualStudio, открываешь, создаешь новое коносльное приложение и делаешь программу по этим требованиям:
- текстовый редактор
- с подсветкой синтаксиса(сисярп хотя бы из коробки)
- файлы могут быть большими(больше 4 гигов один файл)
- поддерживает автоопределение кодировки
- может в undo-redo
- поддерживает плагины
- поддерживает поиск как конкретного слова-словосочетания, так и нечеткий поиск
- может в автосохранение и автовосстановление при непредвиденном закрытии приложения
- автоматическое обновление, без потери обратной совместимости
Вот пока будешь это делать - гуглишь что непонятно. Смотришь видосики, читаешь книги. Как угодно получаешь информацию.
Как только у тебя будет хотя бы демка, возвращаешься к этому видосику - смотришь. Если что-то новое узнаешь - ставишь лойс, если не узнаешь - ставишь дизлойс.
Как то беспонтово. Можно парсить весь двач, тянуть все аттачменты, прикрутить несколько нейронок по детекту нсфв и ненормативной лексики, загрузить все посты куда нибудь в эластик и на всей этой инфе строить прогнозы популярности того или иного треда (из уже агрегированного есть счётчики популярности которые считает сам двач, количество просмотров, постов, уникальных постеров). На основе того что лежит в эластике можно ещё какие то закономерности и прогнозы посчитать.
Тут тебе:
- кор сервис
- постгрес
- еф
- эластик
- кафка/рабит (при желании)
- графана
- s3
- биг дата (?)
- хайлоад (???)
Прикрутив симпатичный гуй, а не графану можно ещё и фронт захватить:
- асп
- аутентификация+авторизация
- веб
- домены
- ссл (лестэнкрипт)
- нжинкс
Так же желательно пройтись по всем граблям обсервабилити
- трейсинг
- метрики
- хелсчеки
Очевидно что если есть всё что выше то нужен и нормальный ci/cd
- гитлаб/гитхаб сборка
- oci
- джокер/кубы
- деплой
Имхо джентельменский набор бэкендера
По началу можно накидать буквально всё под пивас, но после охвата пачки досок и накопления нескольких кк постов будут то там то сям вылезать дыры.
Как минимум это будет что то интересное, уникальное пожалуй, а не очередной мертворождённый редактор который будет хуже всех остальных
Как то беспонтово. Можно парсить весь двач, тянуть все аттачменты, прикрутить несколько нейронок по детекту нсфв и ненормативной лексики, загрузить все посты куда нибудь в эластик и на всей этой инфе строить прогнозы популярности того или иного треда (из уже агрегированного есть счётчики популярности которые считает сам двач, количество просмотров, постов, уникальных постеров). На основе того что лежит в эластике можно ещё какие то закономерности и прогнозы посчитать.
Тут тебе:
- кор сервис
- постгрес
- еф
- эластик
- кафка/рабит (при желании)
- графана
- s3
- биг дата (?)
- хайлоад (???)
Прикрутив симпатичный гуй, а не графану можно ещё и фронт захватить:
- асп
- аутентификация+авторизация
- веб
- домены
- ссл (лестэнкрипт)
- нжинкс
Так же желательно пройтись по всем граблям обсервабилити
- трейсинг
- метрики
- хелсчеки
Очевидно что если есть всё что выше то нужен и нормальный ci/cd
- гитлаб/гитхаб сборка
- oci
- джокер/кубы
- деплой
Имхо джентельменский набор бэкендера
По началу можно накидать буквально всё под пивас, но после охвата пачки досок и накопления нескольких кк постов будут то там то сям вылезать дыры.
Как минимум это будет что то интересное, уникальное пожалуй, а не очередной мертворождённый редактор который будет хуже всех остальных
1. Все это охуеть как скучно.
2. К программированию относится ровно никак, потому что ты просто предлагаешь взять пачку готовых хуевин запустить их разом и смотреть какой мы охуенный конфигуратор-скриптов.
Ничего лучше не писать в контроллерах.
Контроллер пришел из MVC, когда пытались делать по образу-подобию десктопных приложений(на десктопе тогда потихоньку от классических: накидай на форму кнопок, прибей обработчики и погнали - как раз постепенно переходил к MVC, и все что не база - было в контроллере).
Но если уж осталось. Все что касается HTTP - можно делать в контроллере - остальное в сервисе.
Ошибки связанные с бизнес-логикой - тоже лучше в сервисе формировать.
Мидлварем только непредвиденные в духе - все пиздец, все упало, не могу обработать.
Короче. Воспринимай контроллер - как точку входа в приложение. Запрос до сюда дошел, значит базово он удовлетворяет тому что должно быть обработано приложением, все остальное - уже на прикладном уровне обрабатываешь, собираешь. Потом - контроллере - результат отдает.
Ну значит я все правильно плюс минус делал. По поводу ошибок, немного не понял, вот клиент присылает мне неправильный пароль то я кидаю условно throw new appuservalidationerror, и мидлварь перехватывает ошибку и возвращает нужную инфу юзеру где он проебалсся. Это нормальный подход?
У контроллера две задачи: валидировать вход и логировать выход.
На вход в твою апишку могут приехать любые данные от хакера, твоя задача их проверить на инжекшены-хуекшены и отвалиться с ошибкой. Может приехать невалидный токен, которого нет в белом списке, это тоже ошибка. Бизнес логика может бросить эксепшен, его надо поймать, залогировать и вернуть пользователю ошибку 500. Это задачи для контроллера.
В дотнете все это уже реализовано под капотом, ты просто расставляешь аттрибуты. Поэтому в дотнете в контроллере ты просто пробрасываешь данные в сервис, литерали метод из одной строки.
>По поводу ошибок, немного не понял
Берешь и возвращаешь нормальный объект ошибки, который как тебе надо сериализуется.
Как сделать?
Либо Eiter, либо какой-нибудь Result<T>, либо ErrorOr<T> как больше нравится.
> Это нормальный подход?
То что ты кидаешь эксепшины - это самый распространенный подход.
Минус его в том, что у тебя ломается нормальный флоу. У тебя смешиваются в одном месте и реальные исключительные ситуации(место на диске закончилось), и бизнес-ответы.
Результат такого вот подхода:
- ебатория если надо метрики смотреть. Так бы, если реальные ексепшины были, ты просто видел бы в логе сразу пиздец, место кончается, но ты должен будешь охуеть сколько всего настроить, чтобы то же самое видеть
- ебатория с тем, чтобы понять где и почему что-то происходит
- логика прикладного протокола между клиентом и сервером намотана кишками на мидлварь
- проблемы с перформансом, потому что исключение - это не дешевое удовольствие, это сразу хуяк по перформансу
Делал бы нормально, пользуя нормальные подходы, все было бы сильно и проще и красивше и удобнее. Бизнес правила обрабатываются там где должны, перформанс не страдает, а следить за пиздецом на сервере было бы проще.
> Поэтому в дотнете в контроллере ты просто пробрасываешь данные в сервис, литерали метод из одной строки.
Как минимум то, что при использовании FluentValidation валидировать придётся в ручную (из документации). Пакет FluentValidation.AspNetCore признан устаревшим.
> FluentValidation.AspNetCore
Только сейчас узнал из репы т.к. в нугете он всё ещё не депрекейтед. Видать придётся всё на https://github.com/SharpGrip/FluentValidation.AutoValidation переводить либо искать ещё какие варианты. Руками валидировать это мрак
Вот в си-плюсах я могу просто `gcc src/*.cpp -o bin/app.exe -Iinclude -Llib`
сделать и оно само собирется, слинкуется, выдаст файл исполняемый, и никаких csproj и прочего не надо.
Раньше, помню был csc, неудобный, но тоже что-то подобное позволял делать, если однофайловый проект пишешь - было ок.
Но сейчас - хз чем там собирать, если я хочу под линукс, но однофайловый проект сделать.
Ну, Oil rush - не тормозил в момент выхода на ноутбучном железе. Ноутбук был что-то в духе: ноутбучный I3, 4 гига оперативки и дискретка от амуде, Win 7, 1366x768.
Я не особо графодрочер, но тогда графон казался пиздатым вполне.
Из игр на этом движке ток в оилраш играл.
Да не сказать что мыло. Как художник, могу сказать, что можно добиться тех же результатов, что и на анриале и без просадки в производительности. Проблема с этим движком в том, что практически все придется изобретать заново, что в анриале идет из коробки. Даже наличие С# по факту не облегчит жизнь. Проще выучить С++, чем восстанавливать базовый функционал на C#.
А чего там нет-то? Движок довольно давно существует и некоторые фишки, которые в анриале только появились - там уже давно были.
Его проблема как я понимаю была в основном в том, что в руководстве не знали куда его пристроить, и метались из стороны в сторону, выпилив в определенный момент поддержку мобилок, и переориентировавшись на производства и симуляции, плюс - закрытость всего этого дела.
Типа, до того как анрил стал бесплатным для мелких проектов - он тоже не то чтобы прям охуеть как популярен был за пределами AAA, все либо свои движки пилили. Ну, потом еще юнька появилась открытая, и многие на ней пилили.
А вспомнить конец нулевых, начало 10х, всякие индюки и мелкие конторы - либо свое делали, либо на каком-нибудь флеше накидывали прототип, чтобы собрать какой-то фидбек, а дальше - как пойдет.
> Видать придётся всё на https://github.com/SharpGrip/FluentValidation.AutoValidation переводить
Сомнительная идея. 84 звёзды.
> Руками валидировать это мрак
Уж лучше так.
> Сомнительная идея. 84 звёзды.
У оригинала меньше чем 2х за всё время его существования
> Уж лучше так.
Помянем
Ага, до встречи в следующем году с тем же вопросом.
Поищи сливы с озонвского Route256. Там у них есть курс для мидлов. Он как раз про ASP .Net + сопутствующие технологии.
Хочется сравнить эти два языка и расширить свой опыт, чтобы в случае пиздеца было проще найти работу
Типовая структура:
Domain
Application
Infrastructure
WebAPI
По поводу наполнения контроллеров. Контроллер делигирует работу сервису, значит ли это, что сигнатура метода контроллера и сервиса будет одинаковой?
И соответственно все модели реквестов и валидаторы будут в слое Application?
Или же у контроллеров свой реквест, а у сервиса другой и, соответственно, разные модели?
Например:
https://pastebin.com/0Sujn0fJ
Если в приложении доменная модель и модель персистентности (бд) разные, то каким образом выстраивается взаимодействие?
Поправьте меня, если где не прав:
В доменном слое объявляется репозиторий, который использует доменные сущности.
В инфраструктурном слое объявляются модели бд и реализуется данный репозиторий, в котором происходит:
1. Получение модели бд (DAO) через EF
2. Маппинг модели бд в доменную модель
Например:
https://pastebin.com/UHVgZ682
Интерфейсы сервисов Application уровня должны находиться в Domain слое или Application слое?
И зачем закрывать сервис за интерфейсом с одной реализацией?
Типовая структура:
Domain
Application
Infrastructure
WebAPI
По поводу наполнения контроллеров. Контроллер делигирует работу сервису, значит ли это, что сигнатура метода контроллера и сервиса будет одинаковой?
И соответственно все модели реквестов и валидаторы будут в слое Application?
Или же у контроллеров свой реквест, а у сервиса другой и, соответственно, разные модели?
Например:
https://pastebin.com/0Sujn0fJ
Если в приложении доменная модель и модель персистентности (бд) разные, то каким образом выстраивается взаимодействие?
Поправьте меня, если где не прав:
В доменном слое объявляется репозиторий, который использует доменные сущности.
В инфраструктурном слое объявляются модели бд и реализуется данный репозиторий, в котором происходит:
1. Получение модели бд (DAO) через EF
2. Маппинг модели бд в доменную модель
Например:
https://pastebin.com/UHVgZ682
Интерфейсы сервисов Application уровня должны находиться в Domain слое или Application слое?
И зачем закрывать сервис за интерфейсом с одной реализацией?
Чел, у тебя 4 года стажа всего, ты даже в одном стеке еще специалистом не стал.
>Интерфейсы сервисов Application уровня должны находиться в Domain слое или Application слое?
У меня кстати недавно спор был с архитектором на эту тему. Только мы спорили насчет Domain и Contracts
>>34628
>И зачем закрывать сервис за интерфейсом с одной реализацией?
Завтра тебе понадобиться подсунуть другую реализацию, а послезавтра еще и переключаться между ними. Либо перенести эту реализацию куда-нибудь в другой модуль/проект. Сравни количество ебли с интерфейсом и без.
И это типовые задачи, которые возникают постоянно.
> Завтра тебе понадобиться подсунуть другую реализацию, а послезавтра еще и переключаться между ними.
Ни разу не возникало такой необходимости. И сомневаюсь, что она вообще у кого-то итт возникала.
public virtual object Test()
public override string Test()
но не могу изменить тип параметра:
public virtual void Test(object value)
public override void Test(string value)
>У меня кстати недавно спор был с архитектором на эту тему.
Чел, архитектор - это продажник, его задача красиво напиздеть и впарить заказчику допуслуги. Спорить с таким - это как спорить с продаваном в салоне мобилок.
Чтобы LSP не сломать. При наследовании, в классе-наследнике нельзя усиливать предусловия (делать параметры более конкретных типов) и ослаблять постусловия (делать возвращаемые значения более общих типов).
Если ты из метода будешь возвращать строку вместо объекта (object), то для кода, который этот метод вызывал (особенно если не напрямую, а через ссылку на родительский класс) ничего не поменяется, т.к. string наследует object'у. Если ты начнёшь в качестве параметра требовать более конкретный тип (string вместо object'а), то гипотетически, если бы такое собиралось, тебе бы в этот метод через вызов метода после приведения ссылки к типу родительского класс могли бы объект какой-нибудь другого типа запихать. И вот тут уже хз как эту ситуацию разруливать, т.к. конфликт типов.
Подумай, как должен работать этот и что он должен вывести, если бы то, что ты хочешь, можно было бы делать.
class A { public virtual void Test(object value) => Console.WriteLine(value); }
class B : A { public override void Test(string value) => Console.WriteLine(value.Trim()); }
B b = new B();
A a = b;
a.Test(new { huy = "tebe" }); // Что должно тут произойти?
Ещё можешь над вот этим помедитировать
class Param1 {}
class Param2 : Param1 {}
class Param3 : Param2 {}
class A
{
public virtual void Test(Param2 value) => Console.WriteLine($"Param2 {value}");
public virtual void Test(Param1 value) => Console.WriteLine($"Param1 {value}");
public virtual void Test(object value) => Console.WriteLine($"object {value}");
}
class B : A
{
public override void Test(Param3 value) => Console.WriteLine($"Param3 {value}"); // Какой из методов мы сейчас переопределили?
}
Типы аргументов - часть сигнатуры метода. По ней компилятор определяет, какой конкретно код нужно вызвать в месте вызова метода + какой-таки конкретно метод мы переопределяем в классе-наследнике
Подумай, как должен работать этот и что он должен вывести, если бы то, что ты хочешь, можно было бы делать.
class A { public virtual void Test(object value) => Console.WriteLine(value); }
class B : A { public override void Test(string value) => Console.WriteLine(value.Trim()); }
B b = new B();
A a = b;
a.Test(new { huy = "tebe" }); // Что должно тут произойти?
Ещё можешь над вот этим помедитировать
class Param1 {}
class Param2 : Param1 {}
class Param3 : Param2 {}
class A
{
public virtual void Test(Param2 value) => Console.WriteLine($"Param2 {value}");
public virtual void Test(Param1 value) => Console.WriteLine($"Param1 {value}");
public virtual void Test(object value) => Console.WriteLine($"object {value}");
}
class B : A
{
public override void Test(Param3 value) => Console.WriteLine($"Param3 {value}"); // Какой из методов мы сейчас переопределили?
}
Типы аргументов - часть сигнатуры метода. По ней компилятор определяет, какой конкретно код нужно вызвать в месте вызова метода + какой-таки конкретно метод мы переопределяем в классе-наследнике
Не сможете скинуть ссылку на реп, где суперПравильно по всем бестПрактиксам описана вебапи ?
Может кто-то из таких же вкатывающихся смог найти. Я уже устал листать гитхаб
Такого нет. В каждой новой шараге куда ты придешь, у каждого занюханого тимлида будут свои понятия о бестпрактиках и как правильно должен быть устроен API
Мне, как вкатунцу, в свое время очень помогла Ultimate Asp.Net Core Web API от Code Maze. Авторы пишут, что сами довольно большие проекты делали по описанному ими образцу. Я верю этому.
В то же время я не думаю, что все описанное там бест практисес, но для новичка это очень хорошая база, вполне сможешь поддерживаемые и расширяемые проекты делать.
Любой бест практис - контекстуально зависим.
В одном проекте - можно все через минимал апи прямо в Program.cs нахуярить и это будет лучшим решением для данного кейса. В другом - будь добр гексогональную архитектуру и все вот это вот.
Так что одной такой репки нет. Иди смотри разные, пробуй понять, почему так сделано, если имеет смысл в данном кейсе - бери на вооружение, если чел ебанутый и строит интерпрайз левел хелловорды - запоминай что так в данном кейсе делать не надо, если излишне просто для сложных проектов пытается - тоже запоминай и так не делай.
Спасибо, посмотрю
Пока что мой уровень - в контроллере дергать еф. А если какая-то логика часто используется, выносить в отдельный сервис
Буду тогда лопатить гитхаб дальше
>в контроллере дергать еф
Ну вот тут можно уверенно сказать, что в большинстве мест тебе за дерганье слоя данных из контроллеров дадут по рукам. Старайся всегда делать контроллеры максимально тупыми в идеале просто пара строк - вызов нужного сервиса который сделает работу и возврат его ответа наружу.
Просто начни писать юнит тесты.
- DI прокидывает интерфейсы, а State классы
- DI инъектирует в Inject-оре, что позволяет распределять в одном Inject-оре зависимости сразу в несколько классов, а State делает выбор сам в себе (в контексте)
- У State есть переходы в состояниях, в то время как у DI их нет (вот в этом сомневаюсь, по идее я же могу в Injector всё что угодно написать, в том числе и реализовать переходы, храня enum-ы в массиве под каждый класс, чтобы помнить их состояние)
Есть ли ещё что-то, что я упустил? Заранее благодарю за помощь
Многие паттерны по коду выглядят как братья, а то и вовсе близнецы. Поэтому разница в "зачем они нужны", даже если в итоге отличие только в названии.
Декоратор и прокси для класса с одним методом могут выглядеть идентично в реализации. Но все же это разные вещи по семантике название указывает на разницу.
В случае с декоратором у нас просто обернутый объект с полным контрактом, а в случае прокси мы знаем что нам подсовывают заглушку с частичным (а то и иным) контрактом (с целью легковесности или контроля доступа). И вот уже этот наш прокси похож (а то идентичен) на паттерн адаптер по коду...но цель адаптера адаптировать контракт под имеющийся контракт, а не заботиться о весе или контроле доступа.
Так что не смотри на реализацию. Смотри на семантику - она отвечает на вопрос "КАКИЕ ЗАДАЧИ решает паттерн"
Также нет никакого смысла реализовывать паттерн академически. Задачи нужно решать, а не паттерны кодить.
Спасибо за совет, просто это мои первые паттерны и я начал с неправильного подхода в их изучении
>>38308
>"КАКИЕ ЗАДАЧИ решает паттерн"
Вот этого я до конца так и не понял. Если State нужен, когда поведение зависит от состояния, которое меняется во время выполнения программы, то что тогда решает DI? разве не тоже самое?
Эти паттерны решают вообще разные проблемы.
DI это про внедрение зависимостей сервису (классу). Обычно через конструктор (хорошо) или через сеттеры (фука кака). В любом случае тут семантика ИНИЦИАЛИЗАЦИИ, то есть эти зависимости нужны на стадии инициализации объекта.
State же просто подменяет вложенку В ЛЮБОЙ МОМЕНТ в классе не трогая сам объект, который может быть уже у 100500 клиентов захвачена ссылка.
Для возможности замены и выставляется метод смены этой вложенки.
И напомню - не стоит упарываться академически. Есть проблемы - есть общие решения. Не потому что кто то сказал "решать надо так", а потому что похожие проблемы приводили людей к похожим решениям. Эти решения записали и дали им имена чтобы форматировать мозги новичкам, и, что важнее - для коммуникации. Когда тебе сказали "тут такой паттерн", то ты сразу знаешь где чего искать.
Пример решения проблемы. У тебя класс, пишет в базу, база может упасть и тебе нужно в этот момент писать в файл. Что ты будешь делать? 100500 если в каждом методе? Да проще же сделать как в паттерне State (ведь это буквально смена внутреннего состояния), то есть 2 вложенки и один метод который их переключает по своей логике. и ПЛЕВАТЬ что нет внешнего метода SetState - задача решена. В жопу академичность. Нужно ИДТИ К ПАТТЕРНУ и остановиться когда задача решена (с) кириевски вроде
Такой подход лучше всего подходит для io баунд задач и в начале берёт поток для старта задания, потом возвращает поток в пулл, но ивент Луп местный проверяет результат, а потом для обработки результата снова новый поток из пулла берёт. Все так?
И что для серьезных вычислений цпу баунд лучше подходит мультипоточныы параллельный подход с разбиением над подзадачи?
Нужно отделять мух от котлет. TPL (и связанный с ним асинк) являются унифицированным способом работы с тасками (ака задачи). И НИКАК не затрагивает "как оно выполняется" окромя фабрики Task.Run()
Выполнение же отдельно. I/O задачи будут выполнены на I/O потоках, cpu задачи на тредпуле, долгому выполнению можно и поток выделить (тратим время на создание, но зато не занимаем пул), а то и процесс. Или вообще ничего ибо, как я уже сказал, выполнение котлеты, а таски это мухи.
>Если State нужен, когда поведение зависит от состояния, которое меняется во время выполнения программы, то что тогда решает DI? разве не тоже самое?
Вот смотри, пишем конструктор в DI
ClassA(serviceA a , serviceB b)
{
this.a=a;
this.b=b;
}
Теперь что мы не используем DI и вызываем его прям
ClassA()
{
this.a = new ServiceA();
this.b = new ServiceB();
}
Казалось бы разница минимальна и ничего не меняется... Но что если у сервисов конструкторы тоже принимают некоторые сервисы, например БД?
Получается уже такая каша
ClassA()
{
this.a = new ServiceA(new DB());
this.b = new ServiceB();
}
А теперь вопрос, а если нашей БД нужна строка подключения? Пишем вот ак
ClassA(string connectionString)
{
this.a = new ServiceA(new DB(connectionString))
this.b = new ServiceB();
}
А что если если у нас будет ещё несколько классов посредников, например добавим репозиторий или UOW?
this.a = new ServiceA(new UoW(new Repository(newDB(connectionString)));
И кроме того, про строку подключения, должны знать все классы в цепочке.
>Если State нужен, когда поведение зависит от состояния, которое меняется во время выполнения программы, то что тогда решает DI? разве не тоже самое?
Вот смотри, пишем конструктор в DI
ClassA(serviceA a , serviceB b)
{
this.a=a;
this.b=b;
}
Теперь что мы не используем DI и вызываем его прям
ClassA()
{
this.a = new ServiceA();
this.b = new ServiceB();
}
Казалось бы разница минимальна и ничего не меняется... Но что если у сервисов конструкторы тоже принимают некоторые сервисы, например БД?
Получается уже такая каша
ClassA()
{
this.a = new ServiceA(new DB());
this.b = new ServiceB();
}
А теперь вопрос, а если нашей БД нужна строка подключения? Пишем вот ак
ClassA(string connectionString)
{
this.a = new ServiceA(new DB(connectionString))
this.b = new ServiceB();
}
А что если если у нас будет ещё несколько классов посредников, например добавим репозиторий или UOW?
this.a = new ServiceA(new UoW(new Repository(newDB(connectionString)));
И кроме того, про строку подключения, должны знать все классы в цепочке.
Асинки нужны для микросервисов. Ты вызываешь один сервис, другой, десятый, идешь в бд, в редис, до получения ответа тупо ждешь. Параллельно с твоим кодом крутятся еще пару тысяч таких же обработчиков. Выделять каждому по потоку слишком жирно, ведь они большую часть времени ничего не делают. Для таких задач придумали асинки.
Для тяжелых вычислений и для фоновых задач в десктопных программах лучше подходят классические треды. С ними удобнее работать.
к нам жавист с его убогим райнтаймом заглянул?
>в десктопных программах лучше подходят классические треды. С ними удобнее работать.
глупости. в десктопном софте такой же асинк во все поля, а если где надо посчитать то в дело вступает Parallel и LongRunning. В остальное время потоки пула никто не жрет, и выдать поток из пула на долгую работу никак не вредит.
Чувак, ты прям очень доходчиво объяснил, спасибо большое
Пример исчерпывающий и наглядный, благодаря за то что составил его для меня
Асинк на десктопе используют джуны, которые сами не понимают, что делают. Они наслушались хуйни на ютубе про "асинк круто треды плохо" и хуячат асинки везде. Параллел - это прообраз тасок, сейчас уже неактуально.
Треду можно задать параметры при создании. Тред можно просто прибить через аборт, когда юзер нажмет отмена. С тасками придется ебаться с токеном и все равно гладкий юзер экспириенс не получится. Ты просто не сталкивался.
>Асинк на десктопе используют джуны, которые сами не понимают, что делают
ахах лол. скорее это деды используют древние треды напрямую ибо софт был написан 20 лет назад.
>Параллел - это прообраз тасок, сейчас уже неактуально.
сразу видно чела что НЕ РАЗБИРАЕТСЯ в вопросе.
>Тред можно просто прибить через аборт
Все понятно. ты ДЕД который пишет на дотнете 2.0 (не кор)
потому что иначе бы ты знал, что аборта больше нет.
> тасками придется ебаться с токеном и все равно гладкий юзер экспириенс не получится
видимо у тебя лапки. все работает отлично.
единственная проблема - когда чтото не поддерживает отмену, но тут уже не проблема декстопа как такового.
А вот и первый дурачок с ютуба. Поридж, ты бы хоть поинтересовался, почему они задепрекейтили аборт. Правильно, потому что ньюфаги вроде тебя использовали аборт в тасках, вместо дрочения токена, и все ломали к хуям.
я понимаю что ты ответил не тому, а редактировать нельзя. Поэтому я приберегу ушат говна и не буду лить без причины.
гм. то есть ты все же дурачок оказывается
ну ок. народ посмешишь с утра, который тебя прочитает
ну таких дурачков тут много забегает, жависты например.
так что вам привычно выставлять себя имбецилами.
Еще и гордишься этим )))
Всегда мучал вопрос, вот есть доменная сущность. Мы её достаём из бд, потом что-то в ней меняем, а дальше нам её нужно сохранить обратно.
Вы че получается, каждый раз целиком перезаписываете всю сущность? А если это какой-то агрегат где есть дочки, например, хрестоматийный заказ и позиции в заказе. Каждый раз сами отслеживаете что там поменялось?
Ладно если там доменные сущности напрямую через EF мапятся в бд и используется внутренний changre tracker, а если даппер или linq2db?
Просветите, пожалуйста, как это у вас на проекте работает.
> Есть тут адепты DDD и чистой архитектуры?
Ты же в курсе, что это совершенно разные подходы, не совместимые друг с другом?
Первый раз об этом слышу и только от тебя. Обычно наоборот все говорят, что DDD хорошо ложится на чистую архитектуру, как раз все твое ддд лежит в домене.
Ты занимаешься хуйней. Архитектура - это буквально говно без задач, лучшее применение для книг по архитектуре - подпереть ножку стола. Времена абстрактных фабрик прошли, сейчас пишут на голанге с анемичной моделью, а не наворачивают абстрактные абстракции ради абстракций. Надо пересчитать сумму заказа - просто возьми и пересчитай, блеать, это называется проводка, это придумали в 1С еще до твоего рождения.
Спасибо за мнение, анон. Но вопрос был не в том, как мне что-то сделать, а как живут с ддд и чистой архитектурой другие. Я ни то ни то сейчас не использую. Обнял.
Хуево живут. На проде все тормозит, эту проблему пытаются решить апгрейдом железа, цена серверов растет в геометрической прогрессии. Пытаются напердолить многоуровневые кэши, которые всегда глючат, пользователи жалуются, менеджмент отрывается на разработчиках. В какой-то момент приходит новый СТО и решает выбросить к ебаной матери старый DDD копролит и переписать все на микросервисах, без хитровыебаных архитектур. Система оживает.
У меня есть херовый сервак где свет отключают все время
И есть еще один комп
Хочу в крайних случаях включать второй комп и как то синхронить данные в двух базах на этих двух компах
Что гуглить?
Из придуманного запросы последних данных в бд в конкретной таблице и сравнение различий, но может у этого действия есть название
Спасибо
Ты смешиваешь ДДД и работу со слоем данных. Не надо так делать.
ДДД это про то что у тебя есть язык домена, на котором разговаривают условные пользователи твоей программы. И модель, со всеми прикладными частями твоей программы, идет от этого домена.
Т.е. как-бы ты можешь написать программу для учета товаров на складе - говоря на языке нормального такого CS. У тебя просто есть кортежи значений, сурогатные ключи, память, вычислительные модули, процедуры, функции, указатели и вот это вот все. Но в таком случае - будет дохуя лишних преобразований вот этого всего в то что надо пользователю программы.
А можешь - взять и выделить такую сущность как товар, накладная, склад, цена, остатки по складу, дебит-кредит, баланс, и вот эта вся залупа.
А далее - на этот скелет модели - накладываются разделения по тому самому домену - какая часть приложения что должна делать.
Т.е. если со стороны разраба-психопата, можно взять, и в Program.cs все сразу хуйнуть, и оно даже будет работать, а дальше -ебись оно конем; по всем правилам DDD ты проектируешь и сервисы в зависимости от домена, т.е. вот у тебя есть, условно, бухгалтерия, склада, контрагенты и т.д.; у тебя и сервис бухгалтерии появляется, ты спрашиваешь у бухгалтеров, что на вход, что на выход, какие преобразования и как происходят и дотошно воспроизводишь эту всю залупу в программе. А есть люди, которые занимаются приемом товара на складе - у тебя сервис товаров для склада появляется, и вот те же сущности что в реальном мире бы отправлялись со склада в бухгалтерию - отправляются в сервис бухгалтерии из сервиса склада.
Так вот строится "приложение".
А конкретно, как у тебя в БД будет записываться - у тебя должен быть просто инфраструктурный слой, который сделает это максимально эффективным образом. Т.е. скорее всего - раздербанит аггрегаты на сущности, посмотрит, изменилось ли у сущностей что-то из вэлью и если изменилось - то что изменилось - в БД и запишет.
Короче. ДДД это более высокоуровневая абстракция. Если ты думаешь на этом уровне - считай что у тебя где-то есть магическое хранилище, которое умеет делать все так как надо. Думать о ДДД и таких вот низкоуровневых моментах - это стрелять себе в колено.
Да. Зачем это надо. Затем, что программа, внезапно, решает проблему реального мира. И, условная, тетя Залупа Эдуардовна, не знает и не хочет знать, что есть какие-то там базы данных, какие-то непонятные массивы, функции, JWT, бравзеры и прочее, она хочет загрузить файл эксель, нажать кнопку: рассчитать баланс, и пойти пить чай, обсуждая, какая же новенькая Светка - шлюха, строит глазки Петрову, а Петров - тоже хорош, лыбу давит; о, а видели, чо Нюрка учудила, в зеленый выкрасилась, молодиться, стерва, может мне тоже в синий покраситься?
Ты смешиваешь ДДД и работу со слоем данных. Не надо так делать.
ДДД это про то что у тебя есть язык домена, на котором разговаривают условные пользователи твоей программы. И модель, со всеми прикладными частями твоей программы, идет от этого домена.
Т.е. как-бы ты можешь написать программу для учета товаров на складе - говоря на языке нормального такого CS. У тебя просто есть кортежи значений, сурогатные ключи, память, вычислительные модули, процедуры, функции, указатели и вот это вот все. Но в таком случае - будет дохуя лишних преобразований вот этого всего в то что надо пользователю программы.
А можешь - взять и выделить такую сущность как товар, накладная, склад, цена, остатки по складу, дебит-кредит, баланс, и вот эта вся залупа.
А далее - на этот скелет модели - накладываются разделения по тому самому домену - какая часть приложения что должна делать.
Т.е. если со стороны разраба-психопата, можно взять, и в Program.cs все сразу хуйнуть, и оно даже будет работать, а дальше -ебись оно конем; по всем правилам DDD ты проектируешь и сервисы в зависимости от домена, т.е. вот у тебя есть, условно, бухгалтерия, склада, контрагенты и т.д.; у тебя и сервис бухгалтерии появляется, ты спрашиваешь у бухгалтеров, что на вход, что на выход, какие преобразования и как происходят и дотошно воспроизводишь эту всю залупу в программе. А есть люди, которые занимаются приемом товара на складе - у тебя сервис товаров для склада появляется, и вот те же сущности что в реальном мире бы отправлялись со склада в бухгалтерию - отправляются в сервис бухгалтерии из сервиса склада.
Так вот строится "приложение".
А конкретно, как у тебя в БД будет записываться - у тебя должен быть просто инфраструктурный слой, который сделает это максимально эффективным образом. Т.е. скорее всего - раздербанит аггрегаты на сущности, посмотрит, изменилось ли у сущностей что-то из вэлью и если изменилось - то что изменилось - в БД и запишет.
Короче. ДДД это более высокоуровневая абстракция. Если ты думаешь на этом уровне - считай что у тебя где-то есть магическое хранилище, которое умеет делать все так как надо. Думать о ДДД и таких вот низкоуровневых моментах - это стрелять себе в колено.
Да. Зачем это надо. Затем, что программа, внезапно, решает проблему реального мира. И, условная, тетя Залупа Эдуардовна, не знает и не хочет знать, что есть какие-то там базы данных, какие-то непонятные массивы, функции, JWT, бравзеры и прочее, она хочет загрузить файл эксель, нажать кнопку: рассчитать баланс, и пойти пить чай, обсуждая, какая же новенькая Светка - шлюха, строит глазки Петрову, а Петров - тоже хорош, лыбу давит; о, а видели, чо Нюрка учудила, в зеленый выкрасилась, молодиться, стерва, может мне тоже в синий покраситься?
Спасибо за развернутый ответ, только ты ответил не на тот вопрос, что я задавал. Я знаю что такое ДДД и для чего оно нужно. Я понимаю, что сохранение в базу это инфраструктура, которая к ДДД не относится. Вопрос был в том, как именно оптимальным образом реализовать эту самую работу с бд, когда она у тебя существует изолировано.
Ты же не будешь вносить в свой слой домена логику для отслеживания изменений, ведь так? У тебя есть интерфейс репозитория с методом Save который принимает на вход твой агрегат/энтити. И в репозитории твой агрегат становится тупо данными. Как в таком случае реализовать апдейт, каждый раз лезть в базу, извлекать текущее состояние и вычислять дельту?
Тут все зависит от того внутри одного процесса изменения происходят или нет.
Если да - то ты тупо на слой приложения отдаешь прокси, с которым работает твое приложение, и которое фиксирует все изменения состяония. Когда приложение делает "Save", инфраструктурный слой - смотрит, а действительно ли что-то изменилось у данного объекта. Если изменилось - обновляет то что изменилось, если не изменилось - то вообще ничего не делает.
Если межпроцессное(микросервисы, хуе-мое, твоя сущность в 10 разных местах может меняется и гоняется то в жсонах, по grpc, то в XML'ках), то ты делаешь снепшот в момент начала транзакции, когда транзакция завершена, сравниваешь значение которое пришло после, и вносишь изменение если они нужны. Опять же, наиболее оптимальным образом.
Интересный вариант с прокси. Но для прокси же надо будет создавать наследника, а обычно все наоборот воняют, что наследование не кул. Ещё многие рекомендуют максимально все классы делать sealed.
Я вообще не адепт DDD, скорее даже хейтер, просто было интересно как люди борятся со всеми сопутствующими ддд неудобствами.
Спасибо за ответ.
![tumblrb064177e6299f13dab437d477293e0be152946401280.jpg](https://2ch.life/pr/thumb/3218902/17227698052620s.jpg)
>ты спрашиваешь у бухгалтеров
Проиграл на всю квартиру. Как же далеки книжные теоретики от реальной разработки. Ебаного инфоцигана Мартина самого бы отправить общаться с бухами.
>дотошно воспроизводишь эту всю залупу в программе
Потом меняется форма Б10-У я вся твоя красивая модель идет по пизде. Поэтому бывалые разрабы сразу кладут хуй на ДДД и работают с реляционной моделью, она более гибкая.
Просто используй анемичную модель. Забудь про волшебные объекты, которые сами себя отслеживают. Ты литерали создаешь себе проблемы из ничего, потом охуеешь это все отлаживать.
1. ДДД эт не мартин
2. Ты же я думаю тоже не остаешься на уровне голых сущностный реляционной БД. У тебя не Table1 Table2, Table3, а какие-нибудь Users, Roles, Claims, допустим. И у них не Column1, Column2 а Name, Email.
3. С бухами, не ты общаешься. С бухами общается аналитик.
4. Домен не может внезапно взять и полностью поменяться. У тебя как был отчет - так он и остался, просто ты его под новые условия домена изменяешь.
Релационная модель, это либо твое изобретение, либо неправильное использование и понимание того что такое ДДД.
Зайди, блядь, да посмотри структуру той же базы любого бизнеса. Там ВСЕГДА, блядь, идет от структуры той предметной области, в которой оно применяется. Для библиотеки - никто не оперирует понятием таблица, нет, блядь, там всегда будет книга, автор, жанр, читательский билет. Для вуза - никто не оперирует понятием таблица, будут Студенты, Курсы, Преподаватели, Предметы и т.д.
Короче. Да. Если читать не хочешь - так херню не придумывай, будь няшей.
>насколько рабочий план попасть в разработку через администрирование
Не рабочий. Через администрирование реально попасть в девопс инженера, но не в разработчика. При переходе из одной ниши в другую весь опыт обнуляется. Если ты работал в техподдержке а хочешь стать C#-разработчиком, ты начинаешь с нулём опыта в кармане. Они говорят, не ну это понятно что вы работали сисадмином, а вот конкретно с entity framework у вас какой опыт? Ты говоришь, никакого. Они, а ну ясн. Значит начинающий. Причём, это случается даже в пределах одного языка программирования. Если ты пишешь на typescript и используешь react. А им нужно typescript и vue. Тебя спрашивают, а вот вы с vue работали? Ты - не-а. А ну ясн, простите но нам нужен человек который знает vue.
Смотри, у тебя есть Накладная, в ней Позиции. При изменении позиций надо пересчитать ндс.
Рич ооп - у тебя объект Накладная, у него свойство Позиции, ты добавляешь туда объект Товар, а дальше оно само магически внутри все обновляет и пересчитывает. Классика легаси монолитов на джаве.
Анемик ооп - у тебя сервис накладных, у него метод добавить_товар(id_накладной, id_товара, колво). Этот сервис все высчитывает и обновляет. В особо тяжелых случаях рассчеты ведудтся вообще внутри хранимки, чтобы не гонять данные туда-сюда. Обрати внимание, используются не объекты, а интовые id, потому что объект лежит на другом сервере и его еще надо загрузить, а там 100500 полей и у нас таймауты. Так пишут современный бэк на голенге.
В первом случае ты делаешь вид, что никакой бд нет, сети нет, нагрузки нет, все работает на магии и волшебстве. Во втором - ты признаешь, что бд - это самое узкое место в твоей системе и строишь архитектуру вокруг бд, а не вокруг влажных фантазий теоретиков.
Спасибо за ответ. С этим понятно, тогда немного по другому сформулирую вопрос. Какое направление наиболее близко к разработке? Пускай даже косвенно, главное, чтобы полученный опыт можно было считать хоть отчасти релевантным.
>Какое направление наиболее близко к разработке?
Разработка. Не весь опыт одинаково ценен. Если ты пошёл проработал 10 лет говночистом, то тебя не повышают до директора. Ты так и остаёшься говночистом. Точно так же, если ты пойдёшь в какую-то простую нишу, типа техподдержки. Да, у тебя будет опыт. Но ценность этого опыта нулевая, даже со знаком минус. Поскольку техсаппорт считают какими-то мальчиками на побегушках. Ну типа, если ты пожал руку опущенному, то ты сам становишься опущенным. Так же и с саппортом. Отработал - зашкварился.
У меня такое ощущение,что все очень невнимательно читают. Ещё раз говорю, вопрос не в том, что мне использовать, а как эту проблему решают адепты ДДД.
Почему-то самый быстрый код который я видел в своей жизни - был написан именно с применением DDD.
И да, объектики добавлялись в модельку а инфраструктурная магия все что надо делала.
Я не знаю какие там у тебя нагрузки, что надо инты гонять по приложению, но я не думаю что были выше того что было там.
Там был TCP сервер, который обрабатывал заказы с терминалов оплаты, и который 10млн коннектов держал спокойно на сервере с 16 гигами оператвики, и средним RPS в районе полумиллиона на зивончике конца нулевых годов. Еще и сервера были с ХДД. Да. Тот код был на жаве.
Так что МБ все же не в DDD дело? Потому что я не думаю, что у тебя там реально какие-то хайлоады, вот ну не думаю, хоть убей.
Ну да ладно. Жава - медленная, а чтобы было быстро - надо инты гонять.
Иными словами, классический джава копролит с конкаренси, который кеширует у себя всю базу и так работает. Как только ты попробуешь его замасштабировать, он пукнет и умрет. О том и речь, в DDD можно играться на локалхосте, как только ты перезжаешь в облако, DDD идет нахуй. Сейчас не 1995 год, бэк пишут на серверлесе, а не ебутся с мьютексами.
Ну не знаю. Оно до сих пор работает.
Всю базу оно не кешировало. Но да, кеши были для "горячих" вещей.
С масштабированием - единственная беда была в том, что каждому инстансу - нужна своя база, но опять же, там это решалось, уже не буду в детали вдаваться.
![image.png](https://2ch.life/pr/thumb/3218902/17228521331590s.jpg)
ну первое активно используется, а потом приходит анон и начинает орать "ааа (цензура) очень тяжелое свойство сделано так в итоге нужно его запоминать в переменную. Откуда (цензура) я могу знать об этом пид(цензура)"
еще про методы расширения не забывай
они конечно не поддерживают контракт, но и не везде он нужен.
этакий маппер получается.
>И там и там возвращается копия, но свойство хоть и "логичнее", метод для получения копии всё же корректнее, так? Или без разницы?
Когда ты пишешь
public string A {get;set;}
то это автоматом становится
public string _a
public GetA{ return _a}
public SetA(string a) { _a=a}
Второе. И обозвать метод GetShitCopy() чтобы было понятно, что ты именно копию возвращаешь, а не оригинал.
Алсо, как вариант, если Shit не должен в принципе меняться, то проще его сделать record'ом.
Меня забавляют такие челики которые типо знают и другим поясняют.
Челик асинки это сахар , все тоже самое там крутится поток на сервере
>Челик асинки это сахар , все тоже самое там крутится поток на сервере
Используя ThreadLocal и AsyncLocal можно увидеть разницу
Ни то ни другое.
Ты должен в Shit сделать метод: CreateCopy
Вот эта вот хуйня что методом, что свойством - хуйня. Потому что с какого-то хуя Yoba - рождает новые экземпляры Shit.
Если суть существования класса Yoba в том чтобы создавать копии, тогда это должен быть метод. Свойства, семантически - это состояние объекта. Я, как клиент класса Yoba - не ожидаю, что будет создана копия. А потому - делай методом, тогда оно будет понятно.
А что меняется?
А можно.
У меня как раз сейчас проект на авалонии. Так что думаю и в попенсорс можно вкинуться, будет думаю плюсеком в резюме.
Какая же авалония говнина. Как я ненавижу десктопы. Пиздец. Блядь. Будто на 10 лет назад откат в плане того как код пишется.
>>41125
>>41133
>>41412
А если в Yoba самое ценное - это Shit, и, грубо говоря, yoba существует ради shit, но при этом говна в нём как бы нет - публичного нет ни поля, ни свойства, ни даже метода "вот моё говно, смотри", только копию можно получить, но явно не понятно, что это копия говна из именно этого объекта йобы. Как-то это странно, нет?
Понимаю, что пример хуёвый, но если нужно использовать изменяемый ссылочный тип то в любом случае получится хуйня?
Да никого не должно волновать что ты делаешь у себя в геттере. лишь бы это было легким.
Например, из за тупости разрабов шарпа они не сделали Ilist наследником IReadOnlyList, да и вообще я могу захотеть прямо запретить изменение лист
и тогда у меня будет свойство
вот тебе псевдокод
public IReadOnlyList Items => new ReadOnlyWrap(_items)
Идиотизм идеи в том, что список должен быть иммутабельным.
Сама идея листа, это динамический список.
Обдолбятся своим ФП которое уже забыли и сношают потом себя в подобие массивов.
не путай ридонли и иммутабельность
А по хорошему и массив должен быть ридонли, а в шарпе ничего подобного нет.
Законно ли проводить валидацию в маппере?
Ну, если ты под тем - ок или не ок это делать - не ок.
Но блядь. Я сегодня распутывал такую упоротую упаковку спагетти моего коллеги, что валидатор в маппере - это пустяки.
Хах
Ну в вагинаторе конечно отдельно созданном. Но я парился о том, куда вагинатор потом прокинуть, в сервисСущности или маппер
ФлуентАпи не хочу...
Мне.
хорошему программированию. в хорошем программировании для всего используется минимальный и самодостаточный контракт, а не костыли. Но это не к шарпу, где все используют IList и забивают болт на IReadOnlyList ибо неудобно.
В хорошем программировании ты делаешь задачи бизнеса, а не ебешься с бороу чекером или еще какой душной хуйней. Просто потому, что шиз на авторе так решил. Дроч на ридонли интересен только аутистам с окр, нормальным людям похуй.
ага слышали такое. Задачи бизнеса. Хуяк хуяк и в продакшен
А потом бац и оказывается то нулл это ошибка на миллиард долларов. Потом бац -и самолет или космическая станция падает.
Потом бац - и синий экран смерти по всему миру и ущерба на миллиарды.
>>42963
Зато не душно и адвокатно. Да да - АДВОКАТНО, ведь потом только на них надежда чтобы они доказали что ты ничего не должен, что все предоставляется "как есть без гарантий" )))))
и эти зумерки мне еще про иммутабельность что то чешут. смешно просто.
А все потому что
>с бороу чекером или еще какой душной хуйней
зумерки НЕ В ТЕМЕ вообще, поэтому и несут херню.
{ успех, еррорМесседж, результатОперации, возможноЭксепшн } из каждого сервиса и в контроллере решать, какое сообщение клиенту отправить?
А необработанные случаи дополнительно ловить глобальным хэнлдером
На гитхабе листаю проекты, у каждого свой подход, начинаю гуглить минусы и плюсы - разьебывают в ноль
Все 2хх возвращаю как есть без обёрток, всё остальное в одинаковой оболочке с ошибкой, кодом, исключением, трейсидом, для 400 с модел стейтом
Нормальный подход, только он бесполезен сам по себе в вакууме - к нему еще дохуя экстеншенов надо прикрутить, чтобы это все работало как задумано. Типа .IfSuccces, .IfFailure, .Ensure, .Map и т.д. плюс их асинхронные версии. Ну и вяких .ToResultOk, .ToResultFail дженериковых тоже.
Тебя покусал голанговец? В дотнете есть стандартный механизм эксепшенов, используй его. Зачем придумывать err != nil, чтобы что?
Маня, ты же ни дня не работал разработчиком. Твой код никогда не был на проде. Сидишь пердишь на кафедре в мухгу и рассказываешь охуительные истории.
что, порушили твой уютный мирок говнокодинга? ну бывает бывает.
продолжай говнокодить и верить во что хочешь.
Кстати, слыхал про SOLID? в частности, про буковку I из этой аббревиатуры. Не слыхал? ну тоже норма для говнокодера.
Я не он, но обработка штатных ошибок предусмотренных в бизнес-логике/алгоритме через Exception-ы это тоже говно, т.к. при большом их кол-ве превращает код в лапшу. Плюс их особо никак в контракт не зашьеш. Остаётся только в xml doc-ах описывать, что там вылететь может.
Если в коде используются нормальные примитивы для результатов операций, то код, имхо, читаемей выходит. Плюс самодокументируется лучше. Плюс побуждает-таки людей нормально обрабатывать бизнесовые ошибки. А с помощью исключений я обычно по-настоящему исключительные ситуации обрабатываю (разрывы соединений, out of memory, говно каким-то образом прославившиеся в аргументы метода через все валидации и т.д.).
Плюс исключения в горячем коде могут сильно производительность ронять, т.к. их выброс и перехват это достаточно тяжелый процесс.
Нет, не говняк.
Это то к чему приходишь, поебавшись с эксепшинами.
Только самописное - разве что в случае если дохуя свободного времени или оч хочется поучиться как там, но это не на прод.
Для прода - есть готовые всякие ResultOf<T> или ErrorOr<T> и другие расширения. Гуглится легко.
И да - это удобнее, это проще в использовании. Это не ломает твой перформанс, который важен, когда у тебя хайлоад пошел.
Ой, блядь. Проход в джуны. Давай, показывай, как ты твой код будет выглядеть в данном кейсе.
я мимокрок
нормально будет выглядеть, стандартно
а не чужеродно. Тут вам не раст, где исключений нет и поэтому есть средства для удобного разбирания ошибок (хотя приходится их разбирать и компилятор ПОЗАБОТИТСЯ о том чтобы ты не забыл их учесть) и не го, где вроде такая же шняга вместо исключений.
Бутет ебаная каша с постоянными try-catch, будет надо пилить где-то глобальный обработчик исключений.
А потом - тебе прилетит задача: Для всего нового апи - надо фронту возвращать не просто код, а полное описание, что пошло не так, и как пользователь может это исправить, потому что UI/UX'еры почитали хабр, и там жалуются, что ошибки неинформотивные, и надо дать информативные, еще и локализованные, еще и с картинкой красивой сразу с бека, чтобы если фронт не открывается, человек красивую картинку в ответе мог посмотреть.
И вот ты такой полезешь в свой глобальный обработчик и будешь по стектрейсу определять, какое нахуй там апи новое, какое старое, потому что старое - трогать не надо, его при интеграциях используют, и ломать его нельзя.
Вот таким вот хуем, ты на уровне сервиса, если уж надо - все исключения перехватываешь - и возвращаешь контроллеру нормальную ошибку, которую вы договорились возвращать, с локализацией и красивой картинкой.
Это же асп нахуй там в стектрейс смотреть? Да и в целом ты хуйню городишь, но коли в сласть, то сритесь дальше
Вот это фантазии
как раз это с Match будет каша на каждом уровне. А исключения потому такие и есть чтобы НЕ иметь этой каши с матчами/кодами возврата/Error и прочим.
>надо фронту возвращать не просто код
исключения не отрицают код ошибки и любую информацию по ее поводу. А твои матчи не являются волшебной таблеткой ибо страдают тем же недугом - придется плясать если у тебя такие требования. Ведь разницы так то в "что прислать наверх" кроме "как прислать" - явно делая портянки на каждом шагу, или не прописывая, но неявно.
>какое нахуй там апи новое, какое старое, потому что старое - трогать не над
сова на глобусе и хз причем тут твой подход как лечение. Одно с другим не связано.
>возвращаешь контроллеру нормальную ошибку, которую вы договорились возвращать, с локализацией и красивой картинкой
таким же, как и ты - ты где то все равно вынужден будешь прописать "эта ошибка - нам нужно показывать енто". так и тут. Разницы по большому счету нет.
>Разницы по большому счету нет
Разница как минимум в том, что смотря на сигнатуру метода контроллера/сервиса, я сразу вижу, что он вернет и обрабатываю это ровно так же, как обрабатывал бы нормальный результат. В том же месте. Теми же механизмами. Не добавляя try-catch на каждый чих, не делая какой-то непонятный, хрен где зарытый мидлварь для формирования ошибок.
Проиграл в голос. Понасмотрятся своего раста и ябутся в жопы.
Наркоман, какой матч? Какой ретурн нью еррор? Ты совсем ебанулся? Достаточно просто бросить эксепшен, поймать его в глобальном обработчике, записать ошибку в лог и вернуть 500.
>С# - самый лучший язык программирования в мире
Мимо. Нахуя этот самоподдув в прошлом треде?
Не троль. Реально не пойму.
тут 2 крайности. явное против неявного. boilerplate против его отсутствия. Каждый сам выбирает свой стул. В жаве вон есть чекед исключения, но они не взлетели по причине именно "да задалбывает все это указывать".
И не нужно мне говорить что второй стул лучше. Это просто второй стул.
По сути record - это обычный класс, к которому компилятор потом добавляет переопределение некоторых базовых методов (типа ToString, Equals и т.д.)
Я хотел зафиксировать контракт, т.е. что бы в член рекорда можно было только произвольный рекорд записать а не произвольный класс.
Давно не видел, чтобы это слово употребляли в этом значении, лол
Хуйней страдаешь
клиенту все одним кодом ошибки будет возвращаться?
Можно тогда уж на все 200 отправлять, только жсон не слать в ответ
> клиенту все одним кодом ошибки будет возвращаться?
Да, а что? У клиента только один способ обработать ошибку - показать текст ошибки пользователю.
> Можно тогда уж на все 200 отправлять, только жсон не слать в ответ
Можно и JSON слать. { "success": true, "error_message": null, "body": { ... } }
>Я хотел зафиксировать контракт, т.е. что бы в член рекорда можно было только произвольный рекорд записать а не произвольный класс.
Правильно говорят - хуйней страдаешь. Если нужен контракт, то выделяй его и используй.
Да-да. А потом - тебя ебут в жопу клиенты и тестировщики, что ошибки нихуя не понятные, и вообще - на каждую ошибку надо красивую картинку, и текст что сделать чтобы пофиксить, еще и чтобы кнопка была чтобы автоматом пофиксить с клиента. Ну ты понял. Уже проходили, заебало.
>>43843
Второй стул - универсальнее и проще в плане поддержки. У тебя контракт, метод вернет это или ошибку. С эксепшином - у тебя нет контракта. Тот кто его кидает - считает что кто-то поймает. А действительно кто-то поймает - хуй его знает. В результате, у тебя сигнатура:
User CreateUser(CreateUserRequest request);
Но хуй там плавал, там под капотом: CreateUserRequestValidationException чел кинул, или EmailInUseException, или EmailInBlackListException и т.д. и чтобы узнать, что тебе эту хуйню надо обрабатывать - тебе надо лезть в код этого сумрачного гения, и проверять, а кидает он что-то или нет. А с тем, что эксепшины - вверх по всему стеку летят, тебе надо во все что чел вызывает залезть. В пизду короче.
Если хуйня может случиться - вызывающий должен знать об этом явно.
Что в том курсе-то было, лол?
А так - берешь и идешь на собес. Тебя спрашивают. Ты чет не знаешь. Идешь и гуглишь что не знаешь, повторяешь пока не получишь первую работу.
https://learn.microsoft.com/ru-ru/collections/yz26f8y64n7k07?WT.mc_id=dotnet-35129-website
Мне кажется, этого мало для собеса.
Прочитай про ASP, сделай приложение какое-нибудь на основе. С БД и всем таким. Условно - приложение для заказа столиков в ресторане. Или выбери что тебе нравится. Желательно чем бы сам пользовался, чтобы не заебало на середине.
Если оч хочется - прикрути фронтенд.
Собственно. Да.
Как сделаешь - иди на собесы.
![Стикер](https://2ch.life/stickers/riomxKHj/TQJn5YU1_thumb.png)
>А потом - тебя ебут в жопу клиенты и тестировщики, что ошибки нихуя не понятные,
кому понятные? 99% кода что ты используешь как пользователь написано с исклчюениями. мир не умер.
что делать пользователю с подробностями? он не разработчик и детали более нужного ему не нужны.
>Но хуй там плавал, там под капотом:
Ну значит нужно нормальных чуваков код брать. который не будет кидать исключение на валидацию, делать норм исключения и помнить про границы контекста (что является тем самым про что ты задвигаешь. ведь тебе из глубин не придет "деление на ноль", а по пути обернется во что то более общее. Так и с исключениями.
> кому понятные
Конечному пользователю. Че ты тупишь.
>99% кода что ты используешь как пользователь написано с исклчюениями. мир не умер.
Большая часть софта который конкретно я ежедневно использую как пользователь - написана на сях. Какие нахуй исключения в сях?
>что делать пользователю с подробностями? он не разработчик и детали более нужного ему не нужны.
В бесткейсе - информация должна быть достаточна, чтобы пользователь - мог самостоятельно устранить проблему или, а если ее нельзя устранить - понимал причину и не горел, что все пиздой накрылось - глючное говно, по что вам столько деняк плотют.
Шиз, таблетки.
>Конечному пользователю. Че ты тупишь.
что конечный пользователь должен видеть особого кроме того что ему понятно? не вижу как бы монады твои давали больше информации чем можно было бы дать другими путями
ЛИБО ты прописал что показать пользователю, ЛИБО НЕ прописал - монады тут совершенно не причем.
>Большая часть софта который конкретно я ежедневно использую как пользователь
Так и запишем - чел первый день в вебе и не использует никакой сайт кроме двача.
>В бесткейсе - информация должна быть достаточна
>В бесткейсе
>пользователь
ох сколько я видел такое "читай подробности в логе". идешь читаешь - толку ноль ибо ты ничего не можешь сделать кроме как отправить лог в саппорт. в 70% и это не чайники мы.
Обычному пользователю твой стектрейс нахрен не всрался.
![image.png](https://2ch.life/pr/thumb/3218902/17231764289740s.jpg)
![image.png](https://2ch.life/pr/thumb/3218902/17231771703560s.jpg)
Так и свербит сделать как во 2-ом варианте, но добавить аналогичный вызов в A.Add(B b) не получится и методы Add у А и В не равнозначны, и тогда как быть? Остановится на 1-ом варианте?
Первый вариант.
Automapper - хуита. Его любят кодомакаки, потому что с ним кода получается больше, чем без него. Настрочил тонну конфигов и можно показать тимлиду, мол, не бездельничал.
string GetXml(IXmlFormatter fmt)
Да ладно. А альтернативы какие?
Писать свой класс конвертер, да ещё и с интерфейсом, инжектировать, сохранять в поле? И это меньше кода? При том, что для автомаппера можно сказать, чтобы он замапил друг на друга свойства с одним именем и типом, а в конвертере это всё руками надо перечислять.
Есть лучше решение: string Format(T source)
ну так есть куча разных говнорешений - всякие там mapster, maperly, забыл говноплагин под студию что код в редакторе генерит.
>и с интерфейсом, инжектировать, сохранять в поле
почему все так не любят explicit operator ...
Нет))0
если я хочу сделать микросервисную архитектуру – делается ли у вас монорепа? в ноде как раз популярно это. а как у вас? 1 солюшен с подпроектами? какой стек наиболее популярен в прлде? видел много 6 дотнета в вакансиях, почему не 7?
и какие подводные в попытке выбиться в шарповый энтерпрайз? щас все бегают с ГОвном, не сильно ли подкосило кол-во вакансий на .нете?
>делается ли у вас монорепа
Нет. Монорепы зло.
Чаще всего (по крайней мере, то что мне больше всего попадалось), это вынесение модулей, контрактов и т.д. в общие проекты, вроде CommonContracts, CommonServices и т.д. И подключение их уже в репозитории конкретных проектов в качестве git сабмодулей или отдельных пакетов (из собственного нюгет хранилища)
Есть конечно места где монорепы используются, но это чаще всего следствие какого-нибудь местного долбоебизма (вроде ебанутых требований от безов или убеждений тимлида)
>а как у вас?
Обычно: один сервис - один солюшен. Внутри солюшена сервис разбивается на несколько подпроектов, один основной и остальные вспомогательные (например DAL, Domain, AppServices и т.д.). Всякие библиотеки в своих отдельных солюшенах. Несколько библиотек могут в один солюшен объединяться по каким-нибудь признакам.
>видел много 6 дотнета в вакансиях, почему не 7
Потому что 7 не LTS и никто его в прод не потащит, ровно по той же причине никто не требовал 5-й. Вопрос должен быть - почему 6-й, а не 8-й. Потому что в одобренных партией для импортозамещения линуксов в стейбле есть только 6-й дотнет. Можно конечно на свой страх использовать любую версию, но тогда прощай сертификации и здравствуй проблемы от безов.
>и какие подводные в попытке выбиться в шарповый энтерпрайз?
В очень многих местах тебя будут пытаться прогнуть на фулстека.
> щас все бегают с ГОвном
С ним носится хуяндекс в основном. Выглядит все так, будто они вляпались в это говно, а теперь не могут в этом признаться и пытаются на конфах убедить всех остальных, что говно вкусное и полезное.
Дотнет умирает, зря ты сюда вкатываешься. Через 10 лет сишарп будет как делфи сейчас.
Проблема в том, что идеологией дотнета рулят деды, у которых вечно 1995 год. У них в головах до сих пор абстрактные фабрики и 100500 слоев в проекте. Посмотри на Entity Framework, это же ебаный рак мозга, ты не можешь просто сделать запрос к бд без высирания сотен строк конфига.
Почему так взлетели голанг и нода? Да потому что там ты просто пишешь код, который просто работает. Все, блять, никаких солюшенов хуюшенов. Надо сделать запрос в бд - берешь и делаешь, никаких слоев доменной логики и прочей хуйни. Пришли свежие люди со свежим взглядом и выбросили все говно, а в дотнете деды сидят пердят вспоминают свой 1997. Ты сам все видишь по вакансиям, рынок не обманешь.
Алсо по вакансиям. В дотнете это или древнее копролегаси с конкаренси, или фулстек в крипто финтех аи стартап оплата ветками.
>мам в интернете пишут неприятное ну мам
Малолетний дебил, я работаю с дотнетом еще с 2008 студии и прекрасно вижу, в какую пизду он покатился после ухода Гейтса. Майкрософт стремительно проебывает все рынки, а дотнет из энтерпрайза скатился в нишу говна, где фулстек паджиты дерутся за копейки с хохлами. Это литерали новый делфи. Но ты продолжай верить, что через пять лет ты будешь востребованным специалистом с 5 годами опыта на сишарпе за много денег. Учи xamarin blazor, без работы точно не останешься.
благодарю, анонче за развёрнутый ответ. чет действительно, забавно я проебался, спросив про 7, а не 8, знаю ж, что не лтс.
а по вакансиям – реально лучше не слезать с ноды и пробовать дальше в нее тыкаться? я в целом от ебучего жабаскрипта устал, ибо фронтенд - то по пакетному менджеру раз в месяц, то новый фрейм каждый день, то еще какая хуйня вроде стейт менеджеров каждую неделю. уже реакт в базу ходить может, лол. нода тоже не то чтоб далеко ушла, там немного специфики есть, но тоже одних рантаймов штук 5 уже.
я по этой причине думал срыгнуть в тихую гавань типа асп нета или жабы и спокойно себе жить, ибо гошка пока для меня не понятна, ибо есть какие-то компании и в них проекты сильно отличаются от того, что в тырнетах видел
Анон выше прав. Сейчас в дотнете нормальных вакансий, где ты будешь чистым бэком, работать на современном стэке, с современными подходами к разработке хуй да нихуя. И вкатиться на них после смены стэка будет очень тяжело, так как там обычно большие требования (ибо конкуренция). Плюс половина из этого будет что-то околобанковское с характерной бюрократической спецификой.
Плюс учитывая твой бэкграунд с js-ом и нодой каждый первый кабанчик будет пытаться прогнуть тебя на фуллстэка. А это твою проблему фронтовой усталости явно не решит.
Все просто. Смотришь вакансии на мидла по разным стекам. Смотришь на сеньку по ним же, это ты через пять лет. Сравниваешь количество вакансий, зарплаты, насколько охуевшие требования. Понимаешь, что время дотнета прошло и ловить там нечего.
Гошка, кстати, простая и похожа на ноду.
Куда перекатываться с него? В джаву? Гошка кажется слишком радикальной сменой деятельности.
>а по вакансиям – реально лучше не слезать с ноды и пробовать дальше в нее тыкаться?
Ну х.з. я не люблю джаваскрипт и считаю, что с него стоит в любом случае переползать на любой другой стек. Но это мое мнение и оно может не ролять в твоем случае.
С завтрашнего дня, для проектов где я работаю один - я буду использовать TopLevel-only подход. 1 Program.cs на проект. И не ебет.
нееееет. отложи хотя бы до послезавтра.
так и висит. так и везде в мире во всех языках.
Можно ли как-то сделать метод который возвращает дженерик тип, но при этом не указывать сам дженерик тип при вызове метода?
Ситуация - у меня есть поле object в некоем классе в котором будет храниться List<T>.
Если не делать object, то нужно плодить под каждый тип поле, что я не хочу делать.
Теперь при его использовании я хотел написать какой-то метод которой вернет мне эту же object переменную с нужным типом. Сам тип определяется по enum'у этот enum у меня еще много где используется
Но на этом моменте я просчитался - как можно удобно получить нужный тип? Мне нужно что-то типа:
var myListTypeField = myObjectField as GetType(myEnum);
компилятор ниоткуда не узнает выходной тип без указания где то этого типа. В любом случае где то придется тебе его указать чтобы привести к нему.
![image.png](https://2ch.life/pr/thumb/3218902/17236518462240s.jpg)
Давай разбирать по частям тобой написанное.
Я правильно понял, что у тебя ситуация - прикриплейд?
Только CLI, только хардкор.
Ты что-то делаешь не так, потому что usedirect2d работает прекрасно. Только надо еще добавить With(new WindowsOptions() { CompositionMode = new []{RedirectedSurface}), а то окно будет прозрачным.
как его инициировать то надо? посмотреть хочу
Винформс
Что-то типа такого, да.
>>49178
Я могу сделать свич к enum и в кейсах инициализировать поле и писать нужный as type, вот только его нужно будет везде копипастить при обращении к этому полю.
Я не понимаю можно ли как-то сделать из него метод и возвращать Type? Пробовал ковырять возвращаемый тип Type и писать typeof(MyClass), но к конструкции as оно не подставляется.
>>49175
Уже думал. В наследовании к интерфейсу у меня будут теряться те пару полей дочернего класса у родительского интерфейса.
>Пробовал ковырять возвращаемый тип Type и писать typeof(MyClass), но к конструкции as оно не подставляется.
Потому что надо MyGlass.GetType() as
МоёСтекло
Смотря что ты хочешь сделать и смотря для чего.
Если просто нужны какая-то кнопочка и какой-то текстбокс, достаточно юзать винформсы. Стили элементов будут зависеть от конкретной ОС.
Если тебе нужен кастомизируемый UI, то твой выбор WPF, но тут ты должен понимать, что там до сих пор дефолтные стили времен висты и они хуй кладут на то, что у тебя, например, на данный момент стоит одиннадцатая версия виндовс и какой у нее стиль. С одной стороны тебе легче сделать кастомный контрол по сравнению с винформсами, но с другой стороны, вероятнее всего тебе придется перелопачивать стили всех элементов, а в сумме это уже не так-то и быстро. Тут если ты не уверен, что тебе нужно — значит не нужно. Вот мне было нужно, потому что я делал плагины для различных прог и мне надо было выдержать стиль той программы, для которой я делал плагин.
Если тебе нужна мультиплатформа, то твой выбор Avalonia. Это почти WPF, но есть недостатки. Насколько я знаю, там проблемы с растеризацией шрифтов и с виртуализацией списков. Но это самый лучший вариант для мультиплатформы.
Ну или ASP.net, если есть возможность сделать приложение веб.
>разной степени готовности(впф ...
А в чем заключалось неготовность впф? Тем более, что на момент возникновения мауи (который действительно не готов), впф это уже старичок. Единственное, что майкросфот никак не сделает для впф — это не перелопатила стили под свежую ОС. А еще мне самому пришлось делать собственную систему скинов, потому что система тем — это какая-то хуета, подразумевающая перекраску кнопочек аля светлая\темная тема. А вот чтобы у тебя приложение на лету меняло скин с WIN98 на WIN11 — это уже надо как-то делать самому. Да и не сказать, что сделать это сложно — все готово, но каждый раз на это надо тратить время.
Он хуйню написал.
После as должен константный тип быть указан. Это же инструкция для компилятора, а не какая-то конверсия в рантайме.
Я, кстати, до сих пор не понимаю, что тебе надо. Можешь код выложить?
Короче я хотел сделать что-то типа как на втором пике.
Правда уже вижу что компилятор пишет что это таки object.
Пока вижу вариант только с dynamic'ом ковыряться.
Еще хотел чтобы вот этот switch был отдельным методом, а затем там где я использую переменную я бы его дергал, что-то типа
var answerList = dbAnswer.AnswerList as GetMyType();
Ибо иначе мне везде придется копипастить этот switch.
> dynamic
Не вздумай. Максимально спорный черепаший костыль который был введён с одной целью - дружить шарпы с динамическими рантаймами
так то можно этот dbAnswer.AnswerList проверть на null до switch
а не потом
и конечно это object
чтобы это было не object нужно юзать
либо общий класс
либо дженерики
при условии понимания ЗАЧЕМ ОНО ВООБЩЕ (вот с этим проблема)
ты можешь сделать дженерик метод внутри которого будет итоговый тип.
но раз ты можешь его сделать, то, скорее всего, они у тебя и так обладают общим контрактом и можно обойтись тупо интерфейсами.
дженерик метод хорош когда тебе нужно описать шаги.
типа вот у тебя 100500 провайдеров разных данных и тебе нужно из них извлекать, вызывать другие методы (тоже дженерики)
то есть получается много много вызовов разного, а конкретной зависимости от типа нет.
Вот у меня была такая задача - чтение разных данных из разных источников. валидация, фильтрация, сохранение. Данные абсолютно разные - а метод "достал, фильтранул, валидировал, сохранил" один. И я вызываю этот дженерик метод для всех видов данных.
Иначе бы мне пришлось копипастить столько раз, сколько типов данных.
Файл без расширения.
Это как его запустить то?
Если на ставить галочку Создать отдельный файл то есть dll который я собственно потом и запускаю через создание сервиса как в примере
[Service]
WorkingDirectory=/var/www/helloapp
ExecStart=/usr/bin/dotnet /var/www/helloapp/helloapp.dll
.......
А с этим файлом что делать? Так же запускать его просто расширение не писать?
Чел, просто запусти его. Давно ты у линуксовых экзешников видел расширение в конце?
Я ваще не ебу все эти линуксы, делаю просто как в примере, и тут для удобства просто все в 1 файл хотел собрать.
что значит опять?
![image.png](https://2ch.life/pr/thumb/3218902/17237580248740s.jpg)
Там тг бот который берет файлы из папки где он лежит и ни как не связан с /var/www
Хм, нужно карты разложить, а то стекстрейса же нет и смотреть откуда всё идёт ты не можешь
Ну хуй знает
Я переместил бота в папку /var/www/zalupa если ему так хочется.
Хуй знает почему он именну туда лезет, лежал ведь в WorkingDirectory=/opt/TgOrdersBot
Компуктер победил меня корочи.
bump
Оказывается docker файл нужно было переместить на уровень выше. Охуеть блять
Держи в курсе
Почему выбираешь шарп?
У меня фифти-фифти.
Всякие старые клиенты или крупные - чому-то на винде.
Новые - чаще линуксы. Из крупных клиентов на линуксах - сбер.
Самое смешное во всей этой хуйне, что с клиентов что на линуксах - 0 проблем. Развернули им, все годами спокойно работает, периодически только фичи просют. А у тех что с виндой - постоянно что-то с ифрой, все у них ломается, сразу - ваше ПО - хуйня, лежешь смотреть, там админ-долбоеб что-то недонастроел в виртуалке.
НА СОБЕСЕ СПРАШИВАЮТ ПРО КАФКУ, ПРО КАП ТЕОРЕМУ, JWT ТОКЕНЫ, САГИ И ПОСЛЕДНИЕ НОВОВВЕДЕНИЯ В СИШАРПЕ
@
НА ПРОЕКТЕ ДРЕВНИЙ КОПРОЛИТ НА ИИС И ВЕБФОРМС
Забыл машин лёрнинг и хайлоад
Последний раз видел что-то на винде 2 года назад. И то с установкой как можно быстрее её дропнуть и перевести на линукс.
Все новое сейчас точно под линукс и контейнеры сразу разрабатывается. Даже универсальность (чтобы в случае чего запускалась на винде) уже не требуют. Тем более, что вот этот анон >>51775 прав - как оказалось на линуксе оно все проще и стабильнее работает и нет такого дроча как с IIS на винде.
Перед ним должен стоять какой то реверс прокси. Путь винды это iis.
Не тяни эту лямку - иис и винда путь в могилу
![image.png](https://2ch.life/pr/thumb/3218902/17240605763610s.jpg)
- У ченджтрекера отключи вычитывание при инсерте
- Каждую итерацию вставки дергай на ченжтрекере ресет
- Читай с AsNoTracking
- Лучше используй либы для булк инсерта, вся функциональность ефа тебе тут не нужна
Некоторые пункты выше имеют одинаковый эффект но разными способами. Сам читай что к чему
Есть ещё такой лайфхак
for(цикл) {
List<t> myList;
try {
myList = {передаем нужные данные};
}
finally
{
myList = null;
}
}
Как же хорошо что нам на помощь всегда готовы отгрузить пару вагонов вонючек из соседнего треда
Error: В сообщении присутствует слово из спам листа.
Ещё бы написать это так что бы клятый компилятор/рантайм не оптимизировал. Умным дохуя стал, у нас в стариковском вендорлокнутом швайношарпе таких не любят
ну в коде ты протестировал сколько места занимает такое то количество объектов Task + по идее делегатов и плюс еще массив из тасок.
Что измерял хз
async/await это не таски.
Нет никакого срача. Пришел жавист, опозорился, поел говна. Где ту срач то. Тут избиение жавадебила.
Делаешь класс результата (Result например) в котором передаешь собственно результат разоботы сервиса. У него будут следущие свойства:
IsSucces, говорит о том удачно или неудачно отработал сервис
Value - содержит результат работы сервиса если IsSuccess == true
Error содержит объект ошбики, если IsSuccess == false
Ну а в ошибку уже пихаешь что нужно. Либо сразу коды ответа, либо свои внутренние коды, которые в контроллере будут мапиться на стандартные. Плюс всякую муть вроде доп сообщений или эксепшенов.
Ну и в контроллере через какой-нибудь CreateReesponse преобразуешь это все в стандартный ответ.
Всё очень просто, анон. Кидаешь исключение в случае, если что-то пошло не так. И не надо засорять код кучей лапши, как предлагает анон выше.
Короткая вводная.
Бекендомакака. Коллега - ушел в отпуск с нового проекта. Проект - декстопный. Авалония.
Проблема в том, что ЗАВИСАЕТ. Так было когда я пришел вытаскивать, ведь СРОКИ. Суть в том, что бесит жутко. Программулина работает-работает, но в полурандомные моменты времени(полурандомные, потому что после асинхронных операций, но не всегда и не на одни и те же операции) - ЗАВИСАЕТ. И все. Висит пока не убьешь.
Как такое дебажить и искать причину? До этого ни с авалонией ни с десктопом дел не имел.
ну так приатачься и посмотри что там за состояние где висит
и зависает она 99% из за ConfigureAwait(true) по дефолту.
жаба лучше?
требуется пояснительная бригада. как бы евенты это и есть сахар для делегатов, да и сам делегатом является
Лично я считаю дефолтную реализацию ошибкой. Она работает, просто выбор "именно вот так" обладает рядом недостатком.
ну, да, я сейчас и читал на метаните, там все подробно написано, просто я как бы в ахуе, с одной стороны хорошо что есть столько сахара, а с другой я просто боюсь банально не запомнить его)), спасибо анон, теперь буду знать и держать в голове что ивенты лучше
лучше чего? event-ы это и есть делегаты. мультикаст делегат по факту.
а сахар event лишь прописывает за тебя методы добавления и удаления подписок
А сам подход понятен, но выбор неудачен
чтобы отписаться нельзя вызвать какой нить token.Dispose() или лайфтайм передать - нужно передать именно тот делегат, что и была подписка
с многопоточностью вообще беда.
с асинхронностью тоже.
это стандартный механизм реализации паттерна подписчик, но не лучший (хотя идеального не существует - это всегда выбор между стульев с пиками...)
![17230927640690.jpg](https://2ch.life/pr/thumb/3218902/17243264502780s.jpg)
оо, понял, спасибо что просветил анончик
А почему это нет. Самый живой сегмент шарпа. Другое дело если стоит вопрос "где найти бэкенд без необходимости фронтить".
![image.png](https://2ch.life/pr/thumb/3218902/17243373568110s.jpg)
двачую, общался как то с челиком который вроде как микросервисы делал на шарпе, я еще удивился когда узнал что он регулярно, ну типа буквалньо часть его работы копаться во фронте и как то его допиливать, делал он все это по моему на ангуляре, слышал как раз в треде что ангуляр как то по особенному вяжется с шарпом
зацените капчу
>слышал как раз в треде что ангуляр как то по особенному вяжется с шарпом
Никаких особенностей, ровно так же как и любой другой js фреймвор к - через web api
Допустим, я создаю карточку данных сотрудника. В этой карточке три тексбокса и каждый отображает определенное свойство сотрудника: ID, имя и фамилию.
Понятно когда такая карточка предназначена для одного выбранного элемента в списке сотрудников. Но как мне к этой карточке привязать несколько сотрудников? Я не хочу выводить несколько карточек — мне нужна одна, чтобы заполнив поле тексбокса, пользователь разом менял свойства нескольких сотрудников.
Обычно это выглядит так. Если все свойства Name выбранных сотрудников одинаковые, то текстовое поле отображает это имя. Если хотя бы одно значение отличается, то текстбокс остается пустым. Если пользователь вводит значение в тексбокс, то перезаписываются свойства Name всех выбранных сотрудников.
Я знаю про IMultiValueConverter. И я понимаю как вывести данные в сторону текстбокса, но я не понимаю как ИЗ текстбокса перезаписать данные обратно т.к. в этом случае у конвертера нет информации о привязываемом списке.
конвертен не знает - вьюмодель знает. сделай вьюмодель для редактирования карточки и вот она внутри себя будет иметь всех сотрудников 1+ и выводить что надо и обновлять им что надо.
а мультиконверт не нужен
>сделай вьюмодель для редактирования карточки и вот она внутри себя будет иметь всех сотрудников 1+ и выводить что надо и обновлять им что надо.
Но разве это не проблема вьюхи? С другой стороны, сортировка\группировка\фильтрация списков находятся на стороне вьюмодели и там создается отдельное свойство типа ICollectionView. Может мне сделать что-то подобное?
Надо только подумать как сделать это универсальным. У ICollectionView есть свойство Filter, где хранится делегат на метод в котором содержится логика фильрации, а у меня там будет содержаться логика микширования коллекции в один элемент.
Просто тот кто грёб бэк шарповожабовый быстро поймёт концепции ангуляра и что там к чему
int Пук = 5;
Console.WriteLine("{}, Жопа, {0}", Пук);
Ну мне нужны в тексте фигурные скобки, пример упрощённый.
>$"{{}}••••{var}••••"
Чёт я тут не понял. Макаба разметку не поела?
Для примера, вот я хотел вынести работу с компортом в dll.
Если пытаюсь загружать ее через Assembly.LoadFrom(путь) - она загружается, но при попытке что-то сделать получаю PlatformNotSupportedException
Начал гуглить. Нагуглил AssemblyLoadContext. Но при попытке через него загрузиться - почему-то не находит нужный мне тип, чтобы создать дальше объект для работы.
При этом первым способом - другие dll в которых типа нет никаких нативных и прочих зависимостей - нормально подгружаются.
Сначала загружаешь нативные либы (через P/Invoke) и потом уже дотнетовские сборки.
Интересно. Завтра на раб_отке попробую.
И всё таки, чё ж \{ не работает, в чём был сакральный смысл отказаться от такого варианта?
Экранирование исчезает в компайл тайме. Оно и создано для того что бы спецсимволы в исходниках писать. Это единая концепция
>скажем, \n работает, а \{ работать не может?
потому что интерполяции плевать на \n - она для нее ничего не значит, а вот скобкосодержащий продукт значит.
Ну так она же видит перед скобкой слеш, так пусть и обрабатывает должным образом.
> Не понимаю. Почему, скажем, \n работает, а \{ работать не может?
Ты дурак? \n отрабатывается на этапе компиляции, все остальные НЕ эскейп последовательности в рантайме. Это общая договорённость, в исключениях по типу регулярок нужно эскейпить бэкслеш \\n что бы он переходил как текстовый \n в рантайм а не как байтовый перевод каретки
Большинству вообще похуй. Просто здесь году так в 2020 завелось несколько троллей, которые подливают масла то в шарпотреде, то в жаботреде, причём это одни и те же аноны, которые прикидываются то джавистами, то шарпистами.
Что делать с объектами которые не изменяются и хранят в себе настройки для другого класса? При каждом их создании ведь тратится память и создаётся лишняя работа для сборщика мусора. Создавать их каждый раз, использовать синглтон или статический конструктор?
Сам класс осуществляющий работу - ImageConverter. Он не потокобезопасный, что делать в этой ситуации? Создавать новый экземпляр при каждом запуске, или вообще реализовать кеш?
Функция ProcessImage запускается асинхронно через Task.Run в ASP.NET
public class ImageProcessor()
{
public ImageProcessor()
{
var options = new ImageSettings();
options.Format = ImageFormats.JPEG;
}
public MyImage ProcessImage(MyImage image)
{
var converter = new ImageConverter(); // Не потокобезопасный
return converter.Convert(image, options);
}
}
public static class ImageProcessor()
{
public static MyImage ProcessImage(MyImage image)
{
var converter = new ImageConverter();
return converter.Convert(image, new ImageSettings(ImageFormats.JPEG));
}
}
Что делать с объектами которые не изменяются и хранят в себе настройки для другого класса? При каждом их создании ведь тратится память и создаётся лишняя работа для сборщика мусора. Создавать их каждый раз, использовать синглтон или статический конструктор?
Сам класс осуществляющий работу - ImageConverter. Он не потокобезопасный, что делать в этой ситуации? Создавать новый экземпляр при каждом запуске, или вообще реализовать кеш?
Функция ProcessImage запускается асинхронно через Task.Run в ASP.NET
public class ImageProcessor()
{
public ImageProcessor()
{
var options = new ImageSettings();
options.Format = ImageFormats.JPEG;
}
public MyImage ProcessImage(MyImage image)
{
var converter = new ImageConverter(); // Не потокобезопасный
return converter.Convert(image, options);
}
}
public static class ImageProcessor()
{
public static MyImage ProcessImage(MyImage image)
{
var converter = new ImageConverter();
return converter.Convert(image, new ImageSettings(ImageFormats.JPEG));
}
}
{
᠌᠌᠌᠌ ᠌᠌ ᠌᠌᠌᠌᠌᠌ ᠌᠌ ᠌᠌public ImageProcessor()
᠌᠌᠌᠌ ᠌᠌ ᠌᠌᠌᠌᠌᠌ ᠌᠌ ᠌᠌{
᠌᠌᠌᠌ ᠌᠌ ᠌᠌᠌᠌᠌᠌ ᠌᠌ ᠌᠌᠌᠌᠌᠌ ᠌᠌ ᠌᠌᠌᠌᠌᠌ ᠌᠌ ᠌᠌var options = new ImageSettings();
᠌᠌᠌᠌ ᠌᠌ ᠌᠌᠌᠌᠌᠌ ᠌᠌ ᠌᠌᠌᠌᠌᠌ ᠌᠌ ᠌᠌᠌᠌᠌᠌ ᠌᠌ ᠌᠌options.Format = ImageFormats.JPEG;
᠌᠌᠌᠌ ᠌᠌ ᠌᠌᠌᠌᠌᠌ ᠌᠌ ᠌᠌}
᠌᠌᠌᠌ ᠌᠌ ᠌᠌᠌᠌᠌᠌ ᠌᠌ ᠌᠌
᠌᠌᠌᠌ ᠌᠌ ᠌᠌᠌᠌᠌᠌ ᠌᠌ ᠌᠌public MyImage ProcessImage(MyImage image)
᠌᠌᠌᠌ ᠌᠌ ᠌᠌᠌᠌᠌᠌ ᠌᠌ ᠌᠌{
᠌᠌᠌᠌ ᠌᠌ ᠌᠌᠌᠌᠌᠌ ᠌᠌ ᠌᠌᠌᠌᠌᠌ ᠌᠌ ᠌᠌᠌᠌᠌᠌ ᠌᠌ ᠌᠌var converter = new ImageConverter(); // Не потокобезопасный
᠌᠌᠌᠌ ᠌᠌ ᠌᠌᠌᠌᠌᠌ ᠌᠌ ᠌᠌᠌᠌᠌᠌ ᠌᠌ ᠌᠌᠌᠌᠌᠌ ᠌᠌ ᠌᠌return converter.Convert(image, options);
᠌᠌᠌᠌ ᠌᠌ ᠌᠌᠌᠌᠌᠌ ᠌᠌ ᠌᠌}
}
public static class ImageProcessor()
{
᠌᠌᠌᠌ ᠌᠌ ᠌᠌᠌᠌᠌᠌ ᠌᠌ ᠌᠌public static MyImage ProcessImage(MyImage image)
᠌᠌᠌᠌ ᠌᠌ ᠌᠌᠌᠌᠌᠌ ᠌᠌ ᠌᠌{
᠌᠌᠌᠌ ᠌᠌ ᠌᠌᠌᠌᠌᠌ ᠌᠌ ᠌᠌᠌᠌᠌᠌ ᠌᠌ ᠌᠌᠌᠌᠌᠌ ᠌᠌ ᠌᠌var converter = new ImageConverter();
᠌᠌᠌᠌ ᠌᠌ ᠌᠌᠌᠌᠌᠌ ᠌᠌ ᠌᠌᠌᠌᠌᠌ ᠌᠌ ᠌᠌᠌᠌᠌᠌ ᠌᠌ ᠌᠌return converter.Convert(image, new ImageSettings(ImageFormats.JPEG));
᠌᠌᠌᠌ ᠌᠌ ᠌᠌᠌᠌᠌᠌ ᠌᠌ ᠌᠌}
}
Тогда на второй стул садись с пиками точёными
если так напрягает тяжесть создания, то пул конечно
тот же дбконтекст от EF тяжелый и не потокобезопасный и его пулят.
https://www.securitylab.ru/news/551413.php
ох уж эти рейтинги
а реальность такова что либо на жаве сидят деды в легаси (ну то есть уже написано что то на жаве)
либо не написано но жавоеды "нихатим ничего изучать мы долбни"
иначе же жаву активно двигает котлин хотя как бы не заставляют
Ты же даже не жавист, в чем смысл заниматься такими унылыми вбросами? Все адекваты понимают, что жава популярнее, там больше вакух и сытнее зепки. Я бы перекатился, но я слишком ленив, чтобы изучать что-то после работы. Уже 2 года дома не программирую.
Ну, по этому рейтингу - жава с проглотом у питона сосет. Че дальше-то?
Суть. Для разработчика. Жава литерли шарп, но хуже во многих аспектах. Многие вещи - нелогичны или криво задизайнены.
Проблема шарпа очень долго была в том, что он был заперт на винде, а Mono крайне медленно развивался по понятным причинам.
С точки зрения рынка. Вакухи на жаве - это 99% легасиговно, в котором ты будешь с Ant ебаться, или еще какой-нибудь древней залупе, потому что ПАРУ РЕЛИЗОВ пропустили, потом - боялись сломать обратную совместимость, а теперь - переход на современный стек жавовский по трудностям сравним с написанием с нуля не про код приложения, а про то чтобы все это говно просто запустилось, особенно когда использовалась какая-то библиотека древняя, которая вот на этой версии жавы работает, а вот на новой - с какого-то хуя не работает, и да, такой хуйни навалом, особенно если это был какой-то десктоп проект на жаве.
На шарпе, если не вляпываться в десктоп - дохуя проектов на современном стеке, с современными технологиями. Сам язык - дизайнили нормальные люди, а потому - почти каждая фича в тему, и пользоваться ей приятно.
По ЗП, в реальности - +- разрабы получают. Разница на уровне сенек - сопоставима с погрешностью, и не стоит того, чтобы перекатываться на другой стек.
Вот питон - да, база. Но там сеньеры с 1 годом опыта, которые в принципе не представляют, что такое многопоток, перформанс, и вообще, полный треш. Но сам питон - мегабаза, лучший язык для всего, если перформанс не важен.
Спасибо, узнал про существование объектного пула, будем изучать
С явой есть одна проблема, она просто лучше оптимизирована в плане сборщика мусора на данный момент. Сколько лет пилили ZGC и похоже что у C# нет ничего подобного. 1 мс на сборку это сильно
https://stackoverflow.com/questions/64252590/how-does-clr-gc-compare-to-latest-zgc-and-shenandoah-gc-on-jvm
Ничего удивительного. Шарп пилят натуральные макаки, они не способны на что-то большее, чем добавление очередного сахарка. Какие уж там оптимизации сборки мусора
за все нужно платить. любые оптимизации это плюс к пожиранию памяти.
дотнет вот притащил GC DATAS
и новые lock типы они тоже направлены именно на уменьшения потребления памяти
а жаву сколько не корми им плевать. память ом ном ном.
в шарпе меньше мусорят так то. потому и чистить нужно намного реже. Это вам не жава где мусора столько что ПРИХОДИТСЯ чистить ее и вот ваши 1мс превращаются в "много раз по 1мс"
>Ты дурак?
А может ты пидор?
Вот смотри, глобально же нет разницы как делать так \{ или так {{.
Но если сделать так \{, то компилятор даст ошибку, ибо не знает такой последовательности.
Так вот всё что нужно было сделать это прописать в компиляторе пропускать последовательность \{ без изменений. И вопрос был бы решён, был бы единый общий подход к экранированию, без этой {{ херни.
Ну ладно, как есть так и есть, мой вопрос собственно в другом.
Мне надо распарсить текстовый файл, содержащий помимо латинских слов ещё и кириллицу, файл в аски-кодах.
Я тут узнал что char и string оказывается двухбайтовые и работают в уникоде. Ещё прифигел когда узнал что можно давать названия переменным русскими буквами.
Попытался считать из файла несколько символов кириллицы и вывести в сосноль, закономерно увидел ????. Как быть? Наверно сконвертировать одно в другое и обратно можно?
> Но сам питон - мегабаза, лучший язык для всего, если перформанс не важен.
А что там по UI? Чет я смотрел, и там возможности скуднее винформсов.
По вопросу луче что-нибудь скажи.
> As for why async methods don't support out-by-reference parameters? (or ref parameters?) That's a limitation of the CLR. We chose to implement async methods in a similar way to iterator methods -- i.e. through the compiler transforming the method into a state-machine-object. The CLR has no safe way to store the address of an "out parameter" or "reference parameter" as a field of an object. The only way to have supported out-by-reference parameters would be if the async feature were done by a low-level CLR rewrite instead of a compiler-rewrite. We examined that approach, and it had a lot going for it, but it would ultimately have been so costly that it'd never have happened.
![2024-08-2514-08-51.jpg](https://2ch.life/pr/thumb/3218902/17245842094700s.jpg)
Дорисовал картинку.
int32_t yices_get_unsat_core(context_t ctx, term_vector_t v)
Причем term_vector должен быть инициализирован другой функцией из этого апи:
void yices_init_term_vector(term_vector_t v)
Сам терм вектор это просто
typedef struct term_vector_s {
uint32_t capacity;
uint32_t size;
term_t data;//alias int32_t
} term_vector_t;
Мне собственно, нужен этот массив интов, думаю. Как адекватно это делать? Создать стракт в шарпе и маршаллить в него? Как адекватно его создать, у меня пока что-то такое: [StructLayout(LayoutKind.Explicit, Size = 12, Pack = 4)]
struct term_vector
{
[FieldOffset(0)]
private uint capacity;
[FieldOffset(4)]
private uint size;
[FieldOffset(8)]
private IntPtr data;
}
Но я видел, что вроде поля как-то нужно помечать, если в них маршаллить из unmanaged памяти что-то хочешь. По теме я нашел пару похожих вопросов в инете, но там уродски написано, не понял, если знаете где более-менее объяснили это, то скиньте пожалуйста
По-моему, буквально, твой пример: https://learn.microsoft.com/en-us/dotnet/standard/native-interop/type-marshalling#marshalling-classes-and-structs
И у тебя будет что-то типа:
void yices_init_term_vector(out term_vector v)
int yices_get_unsat_core(context_t ctx, ref term_vector v)
(как я понял ctx это просто opaque pointer, так что вставь нужный тебе pointer-sized тип который нормально маршаллиться: void или IntPtr/nint)
[StructLayout(LayoutKind.Sequential)]
public unsafe struct term_vector
{
public uint capacity;
public uint size;
public int data;
}
А вообще, так как я маршаллинг практически не знаю, я бы сделал так (если я правильно понял API):
int yices_get_unsat_core(void ctx, term_vector v);
void yices_init_term_vector(term_vector v);
public unsafe struct term_vector
{
public uint capacity;
public uint size;
public int data;
}
(хотя ctx можно заменить на какую-нибудь простую обёртку над void*/IntPtr, и она будет нормально маршаллиться без каких либо телодвижений).
Ну обращаться к данным можно как:
new Span<int>(v.data, checked((int)v.size))
Вот оба варианта скриншотом (из SharpLab'а).
И что-то я не нашёл как маршаллить массив переменной длины внутри структуры из unmanaged в managed (может и можно как-то через LibraryImport и кастомные маршаллеры, но я давно привык пердолиться ручками и эти новые штуки я даже не пробовал. Может тут, в треде, есть эксперты маршаллинга и они знают как?).
Stack Allocation Enhancements
https://github.com/dotnet/runtime/issues/104936
Спасибо большое, отпишусь, как добью всё до минимально рабочего состояния
>Encoding.UTF8.GetString
>Encoding.ASCII.GetString
Во-первых, почему UTF8 когда уникод двухбайтовый?
Во-вторых, они не могут в кириллицу.
Давай расскажу подробнее что мне надо.
Вот есть у меня файл тхт.тхт, кодовая страница 1251, следующего содержания на самом деле значительно сложнее, но пока так
qwerty
йцукен
Мне в нём надо искать разные подстроки, считать количество букв в словах и тд.
Почти все эти задачи реализованы в String. И вот чтобы не пердолиться, тоже самое самому не писать, а применить уже имеющееся, я копирую содержимое файла в строку
string DumpFile = File.ReadAllText(тхт.тхт);
Так вот все латинские буквы оно конвертирует автоматически, получается как-то вот так 0х0069, 0х006Е, 0х0069,0х0065, а вся кириллица переходит в 0х003F, 0х003F, 0х003F, короче знак вопроса. Если вывести на экран
qwerty
??????
И никакие
string DumpFile = File.ReadAllText(тхт.тхт, Encoding.ASCII);
и
Encoding.Convert(Encoding.ASCII, Encoding.Unicode, DumpFile);
не помогают. Ничто из этого не может в кириллицу, результат один - вопросики.
Ну а вообще ты наглухо ослеп (лол), хоть перегрузки методов иногда смотри, а не копипасть всё из чатжпт
Я думал, что freezable-объекты автоматом будут это делать. В MDSN написано, что если класс не содержит DependencyProperties, то нужно самому позаботиться об обновлении, но ни WritePreamble(), ни WritePostscript() эффекта не дали.
Я банально копирую вот эти три метода и толку ноль:
public void Add(T item)
{
AddHelper(item);
}
private int AddHelper(T value)
{
int index = AddWithoutFiringPublicEvents(value);
WritePostscript();
return index;
}
internal int AddWithoutFiringPublicEvents(T value)
{
int index = -1;
WritePreamble();
index = ((IList)_collection).Add(value);
++_version;
return index;
}
Подозреваю коллекцию _collection странного типа FrugalStructList которая волшебным образом отслеживает изменения итемов, но в чем тогда смысл городить freezable-коллекции?
Исходники оригинальных freezable-коллекций:
https://source.dot.net/#PresentationCore/System/Windows/Media/Generated/GradientStopCollection
https://source.dot.net/#PresentationCore/System/Windows/Media/Generated/DoubleCollection.cs
Я думал, что freezable-объекты автоматом будут это делать. В MDSN написано, что если класс не содержит DependencyProperties, то нужно самому позаботиться об обновлении, но ни WritePreamble(), ни WritePostscript() эффекта не дали.
Я банально копирую вот эти три метода и толку ноль:
public void Add(T item)
{
AddHelper(item);
}
private int AddHelper(T value)
{
int index = AddWithoutFiringPublicEvents(value);
WritePostscript();
return index;
}
internal int AddWithoutFiringPublicEvents(T value)
{
int index = -1;
WritePreamble();
index = ((IList)_collection).Add(value);
++_version;
return index;
}
Подозреваю коллекцию _collection странного типа FrugalStructList которая волшебным образом отслеживает изменения итемов, но в чем тогда смысл городить freezable-коллекции?
Исходники оригинальных freezable-коллекций:
https://source.dot.net/#PresentationCore/System/Windows/Media/Generated/GradientStopCollection
https://source.dot.net/#PresentationCore/System/Windows/Media/Generated/DoubleCollection.cs
![изображение.png](https://2ch.life/pr/thumb/3218902/17247096695290s.jpg)
А здесь есть проблема? Сначала в консоль в качестве отладки, потом надо будет обратно перегнать в 1251 и записать в файл.
>>56945
Так как её взять то?
>>56947
Что мог то смотрел, с чатжпт ничего не копипастил. У меня вот эти три книжки есть, оттуда и брал.
Не забывай я - нуфаг, много от меня не требуй, лучше покажи как делать.
> Debug.Assert now reports assert condition, by default.
https://github.com/dotnet/core/blob/main/release-notes/9.0/preview/preview7/libraries.md#debugassert-now-reports-assert-condition-by-default
В .NET Core 3.0 добавили CallerArgumentExpression аттрибут.
В .NET 6 начали его поддерживать.
И только в .NET 9 они приклеили это к Debug.Assert() (с помощью OverloadResolutionPriority).
каким еще волшебным способом
/// Extenders of Freezable must call this method at the end of an API which
/// changed the state of the object (e.g., at the end of a property setter) to
/// raise the Changed event. Multiple state changes within a method or
/// property may be "batched" into a single call to WritePostscript().
///
protected void WritePostscript()
который вызывает событие Changed
никакой магии
>никакой магии
Так вот нихера не происходит. Я тебе привел в пример кусок кода, где используется WritePostscript при добавлении итема.
Вот смотри. Есть майкрософтовский freezable-класс GradientStop, в котором есть два DP свойства: Color и Offset. Есть freezable-коллекция GradientStopCollection, которая хранит в себе элементы типа GradientStop.
Так вот, если я в одном из добавленных итемов GradientStop изменю значение свойства Offset, то это вызовет собите Changed сперва у GradientStop, затем у GradientStopCollection.
А вот у моей кастомной коллекции, где используется данный код >>57087 при изменении Offset не возникает события Changed. Это событие возникает разве что при изменении самой коллекции, например в выполнении метода Add. И вроде как логично, ведь этот метод запускает WritePostscript().
А магия заключается в том, что что-то где-то в коллекции чекает изменение СВОЙСТВА итема этой коллекции , но никаких подписок я не нашел. Если не понятно, то я могу скинуть проект.
>при изменении Offset не возникает события Changed
И чтобы уточнить. Сам экземпляр GradientStop при изменении Offset вызывает событие Changed. Но вот моя коллекция это событие не детектит, и соответственно не вызывает свое событие Changed.
Ты небось ищешь подписку коллекции на итемы стандартными методами
Я хз как там на самом деле но если глянуть по диагонали твою же градиентстопколлекцию, то в глаза бросается вызовыOnFreezablePropertyChanged( который в свою очередь вызывает
context.ProvideSelfAsInheritanceContext
И точно так же и отписывается через OnFreezablePropertyChanged
>OnFreezablePropertyChanged
А ты через что смотришь? source.dot.net не показывает что там внутри.
https://www.dotnetframework.org/default.aspx/Net/Net/3@5@50727@3053/DEVDIV/depot/DevDiv/releases/Orcas/SP/wpf/src/Core/CSharp/System/Windows/FreezableCollection@cs/1/FreezableCollection@cs
но вообще я просто прошел через декомпил из студии. иначе ж в этом тексте хрен куда перейдешь.
>иначе ж в этом тексте хрен куда перейдешь.
В source.dot.net обычно можно, там все кликабельное, но есть элементы для которых ссылка отсутствует, либо ведет на пустую страницу.
Library.Books.Add(new BookLibrary(){
Library = Library,
Book = new Book()
});
Приходится сначала добавлять в DbSet книгу, и только потом добавлять промежуточный класс с ней, иначе ошибка FOREIGN KEY что-то там.
Можешь, но ты видать со схемой обосрался
bump
Как из функции вернуть несколько значений? В старом добром Си я бы передал в функцию сколько нужно указателей и через них вернул бы значения. А тут как? Тут нет указателей же.
Тебе уже 10 раз пояснили. Возьми нужную кодировку и прочитай файл с ней.
Что не понятно? Могу тебе даже запрос в гугл составить: c# read file with encoding
![2024-08-2802-16-39.jpg](https://2ch.life/pr/thumb/3218902/17248010572880s.jpg)
- ref/out
- создаешь структуру с каким угодно количеством параметров и возвращаешь ее. Для ленивых придумали кортежи (их два вида), которые под капотом автоматически делают что-то типа структуры или класса (в зависимости от вида). Еще есть анонимные типы — их использовали до кортежей.
Типы кортежей:
https://learn.microsoft.com/ru-ru/dotnet/csharp/language-reference/builtin-types/value-tuples
Выбор между анонимными типами и кортежами:
https://learn.microsoft.com/ru-ru/dotnet/standard/base-types/choosing-between-anonymous-and-tuple
Не знаешь что такое синдром утенка и "со своим уставом в чужой монастырь не ходят"?
Выросло поколение зумеров блин, классики не знают.
Пиздец это тащить в новый яп привычки со старого. такое иногда можно встретить. Приходит какой нибудь абстрактный жавист или пхпэшник в питон и начинает срать на стиль (вон в питон есть даже стандартный модуль логгинг, где стиль отличается от питонического) и плодить абстракции ради абстракций, которые в питоне нахрен не надо.
Пхп так вообще клинический случай в своем рождении - сборище функций, где каждый пилил "а мне так удобно вот идите нах"
Точно так же в шарпе out параметры являются только лишь непривычными для тех кто пришел откуда то, а не неудобными или еще как.
Давай еще повсеместные TryGetValue(..., out var ) в кортежи оборачивай. Ну типа так тебе удобнее.
да. используй списки List<KeyValuePair<TKey,TValue>> и ищи в них последовательно. Как нашел - выдавай кортеж.
Кстати, если сделать один список на приложение, то GC напрягаться не будет. Экономия.
Крайне рекомендую
Имеем List<byte[]> миллионы итемов и идет по ним поиск. Само собой привет HashSet, но это все же память, да и byte[] это аллокации.
Уменьшаем память - сортируем, склеиваем все в один большой byte[] и пишем бинарный поиск. Сравнение элементов не пишем, ведь есть arry.Slice(...).SequenceCompareTo(..)
Все работает, на 25% медленнее HashSet, что ожидаемо.
Ради изучения раста пилю то же самое на расте 1 в 1 и бенчмаркаю (миллионы элементов поэтому время само собой относительное)
шарп (HashSet) - 211 ms
шарп (бин поиск) - 287 ms
rust (бин поиск) - 252 ms
конечно в rust есть еще simd, но это еще нужно с ним как то приседать. А в шарпе присели за меня.
В чем дрочь? В анрил энжине в С++ в норме вещей, когда метод возвращает структуру, если возвращаемых значений несколько. Передают по указателю только 1-2 элемента. Да даже два много.
В шарпе ровно та же система, только навалили сахарку, чтобы ты с созданием структур не ебался.
>Я проще массивы одноэлементные объявлю.
Одноэлементный это типа одномерный? Глупость какая-то. Обосрешься т.к. несколько итемов будут иметь разные типы. Ты в object собрался их пихать? Не дури и возвращай структуры как отцы в С++, а если ленивый, то возвращай кортежи.
Если самому список держать, то нет смысла KEyValuePair хранить, лучше именованный кортеж. Правда мне часто обновлять значение надо, неудобно наверное кортеж пересоздавать.
>List<KeyValuePair<TKey,TValue>>
Ключ-пара ридонли. Задолбаешься.
Видел как выглядит словарь? Он хранит три списка: один для ключей, один для значений и один для хеш кодов (это чтобы по ключам не искать). А ключ-пару словарь создает только когда ты от него это просишь, например когда пытаешься использовать словарь как список. Словарь изначально не содержит в себе KeyValuePair, это создается на ходу при запросе.
![Стикер](https://2ch.life/stickers/fyg4EuYM/x6EuBOrm_thumb.png)
Один предлагает ключ-пару в списке хранить, другой предлагает хранить кортеж.
>Как не задолбаться в этой ситуации???
Иметь структуру или класс в качестве элемента.
Dictionary в себе содержит список структур типа Entry:
private struct Entry
{
public uint hashCode;
public int next;
public TKey key; // Key of entry
public TValue value; // Value of entry
}
Железо ведь копейки стоит, всегда можно докупить.
Двачую этого господина. Вот, например, яндекс диск для синхронизации файликов кушает почти гигабайт. А что такого? У юзера оперативы 32Гб, ему жалко что ли? Ну и что, что он только запустил комп, а у него уже нет 30%? Делать из этого трагедию?
Батчами по 10к записей. На каждой итерации дергать ресет на дб контексте, отключить вычитывание при вставке в тех же настройках
Ещё параллелизм накрути, 10-20 тасок по 5-10к в батче можно спокойно ставить
Погугли термин Upsert
Я ещё охуенную оптимизацию придумал - разбить этот жиссон на 10 жиссонов
Cанкции. Железо всё :С
Если есть возможность, то индексы еще ебани на время вставки, а потом верни обратно.
Вот тебе лучей бобра за конкретный пример.
Осталось непонятным зачем нужна строчка 9, у меня на неё компилятор ругается, такие имена не знает, а код адекватно работает и без неё.
Оказывается такой код не компилируется
int i = 3; //1
{
int i = 5; //2
}
Вторая i, внутри скобок, по всем законам жара, должна перекрывать первую. Но вместо этого просто выдаётся ошибка.
Извините, господа хорошие, но это пиздец. В чём тут принципиальная позиция?
Без нее может ругаться что кодировка 1251 не найдена. Сам не знаю зачем так сделано что нужно добавлять такую строку
Это сделано когда кодировки тянутся из нугет пакета. Всякие закорючки и прочие копролиты кикнули в него. В фреймворке на сколько помню всё сразу было в стандартной поставке
Ну я добавил эту строку не ради красного словца, а потому что без нее ругалось и не работало. В этот раз не пришлось ставить пакет с нюгета как раньше, но без строки не заработало.
Я из-за этой пораши не могу элементарный цикл вставить.
int i;
...
for(int i=0; i<=15; i++)
{
...
}
>>57809
>ref, out
Ну похоже это то что надо.
>Кортежи
Не взлетели. Может из-за того что у меня вижуал студия 2013 старая?
>>57809
>создаешь структуру с каким угодно количеством параметров и возвращаешь ее.
Городить структуру ради двух переменных это какое-то извращение ради извращения.
>Еще есть анонимные типы — их использовали до кортежей.
Загуглил на скорую руку, с наскока ничего не понял, может позже к этому вернусь.
>>57832
>А возня с указателями типа не дроч?
А в чём тут дроч?
>>57840
>Не знаешь что такое синдром утенка и "со своим уставом в чужой монастырь не ходят"?
>Выросло поколение зумеров блин, классики не знают.
Я так то скуф уже. Но про утёнка не знаю, да. А про устав ты говоришь в контексте что я с ним куда-то лезу, я я никуда не лезу, вот я тебя и не понял. Я всего лишь зашёл спросить как тут люди без указателей живут. Оказывается какое-то подобие указателей таки есть.
>>57919
>В чем дрочь? В анрил энжине в С++ в норме вещей, когда метод возвращает структуру, если возвращаемых значений несколько. Передают по указателю только 1-2 элемента. Да даже два много.
Не знаю как там в анрыле, может там специфика такая, но я даже ради пяти элементов структуру не буду делать. Это же надо её объявить, имя придумать, и всё только ради чтобы применить один раз.
>Одноэлементный это типа одномерный?
Нет это типа
int[] A = new int[1];
Работает чётка. И ref/out уже не нужны.
>>57809
>ref, out
Ну похоже это то что надо.
>Кортежи
Не взлетели. Может из-за того что у меня вижуал студия 2013 старая?
>>57809
>создаешь структуру с каким угодно количеством параметров и возвращаешь ее.
Городить структуру ради двух переменных это какое-то извращение ради извращения.
>Еще есть анонимные типы — их использовали до кортежей.
Загуглил на скорую руку, с наскока ничего не понял, может позже к этому вернусь.
>>57832
>А возня с указателями типа не дроч?
А в чём тут дроч?
>>57840
>Не знаешь что такое синдром утенка и "со своим уставом в чужой монастырь не ходят"?
>Выросло поколение зумеров блин, классики не знают.
Я так то скуф уже. Но про утёнка не знаю, да. А про устав ты говоришь в контексте что я с ним куда-то лезу, я я никуда не лезу, вот я тебя и не понял. Я всего лишь зашёл спросить как тут люди без указателей живут. Оказывается какое-то подобие указателей таки есть.
>>57919
>В чем дрочь? В анрил энжине в С++ в норме вещей, когда метод возвращает структуру, если возвращаемых значений несколько. Передают по указателю только 1-2 элемента. Да даже два много.
Не знаю как там в анрыле, может там специфика такая, но я даже ради пяти элементов структуру не буду делать. Это же надо её объявить, имя придумать, и всё только ради чтобы применить один раз.
>Одноэлементный это типа одномерный?
Нет это типа
int[] A = new int[1];
Работает чётка. И ref/out уже не нужны.
>у меня вижуал студия 2013 старая?
>Городить структуру ради двух переменных это какое-то извращение ради извращения.
>я даже ради пяти элементов структуру не буду делать. Это же надо её объявить, имя придумать, и всё только ради чтобы применить один раз
>int[] A = new int[1];
>Работает чётка. И ref/out уже не нужны.
Ты смешной.
>Нет это типа
>int[] A = new int[1];
А смысл заключать один элемент в массив, когда ты можешь и так вернуть один элемент? Представляю какой у тебя бардак в коде, когда метод принимает условный массив из нескольких элементов и правит их по индексу. Учитывая твою лень, там еще и документации нет, лол.
>может там специфика такая
В анриле в норме вещей возвращать комплексные данные, типа матриц трансформаций, или элементов инвентаря. Создают структуры пачками и не бухтят. Но за пределами игростроя я редко встречаю задачу, когда мне необходимо возвратить много не связанных между собой значений, которые применяются один раз. В большинстве случаев это намекает на то, что метод перегружен функционалом и берет на себя слишком много задач.
>я даже ради пяти элементов структуру не буду делать. Это же надо её объявить, имя придумать, и всё только ради чтобы применить один раз
Организованность должна быть. Если твои функции шатают 5 и более параметров по ссылке — это же пиздец какой-то даже в плане читаемости кода. Я пользовался методами WinApi, которые написаны на С++, и не встречал чтобы по ссылке принималось больше чем один объект. Даже условный метод получения координат курсора требует ссылку на одну POINT структуру, а не две ссылки X и Y.
>BOOL GetCursorPos(
> [out] LPPOINT lpPoint
>);
Хз по каким говнокурсам ты учил С++, но что-то явно не так.
По затраченному времени? По строкам кода? По функционалу программы?
Ну да. А что?
Что за вопросы?
Очевидно что: (затраченное время * коэффициент опыта)
>По строкам кода
Только если ты индус. Можно сказать "а что мешает мне навалить кучу строк?" или "что мешает мне затягивать время?".
Но если речь идет о добросовестном исполнении, время может тратиться и на другие вещи, помимо кода, поэтому оно более содержательно.
>По функционалу программы?
Ты будешь держать таблицу всех возможных вариантов функционала с прайсом? Если у тебя уже готов конвейер с готовыми решениями, то может такой подход и имеет смысл.
>>58835
Ну я просто хз как я беру по рынку или нет.
Я оцениваю примерно по затраченному времени ну и если функционал прибавляется то и время прибавляется.
В основном мелочь делаю, тг боты регеры парсеры 100-200$ вот хуй знает это по рынку или нет.
Как то клиент говорил что уже заказал бота 50$ ему мозг месяц ебали в итоге все криво работает и с ошибками. Я сделал за 180$ за неделю. Не ну так то за 30 часов наверное сделал, просто неделя ушла на переспросы и ожидание ответов.
я отвечал тому кто написал
>Я проще массивы одноэлементные объявлю.
А так...
>Городить структуру ради двух переменных
для этого же есть туплы всех видова размеров цветом и с подогревом
>Я всего лишь зашёл спросить как тут люди без указателей живут
да так же как и без goto - не особо знаем куда пихать goto и указатели если и без них норм.
туплы в старом варианте для некрофилов это просто Tuple<T,T> которые подключаешь с нюгета и некрофилишь.
Точно так же как и Action<T.... вместо "объявляем делегаты"
А зачем сидеть на 13 студии - не понимаю да, лучше бы сидел на 2005
Да, используется повсеместно, сильно уменьшает объем кода.
А ты потешный.
>>58899
>туплы
Не знаю что это.
>без goto
Ну так-то goto иногда удобно.
>>58648
>Хз по каким говнокурсам ты учил С++, но что-то явно не так.
Я - не вы, чтобы по говнокурсам учить. Я в шараге учил, ну и сам в основном.
>Учитывая твою лень, там еще и документации нет
Какая документация, о чём ты? Я софтину почти для собственных нужд пишу.
>А смысл заключать один элемент в массив, когда ты можешь и так вернуть один элемент?
А мне надо несколько, притом разнотипных. Вот я и объявляю несколько разнотипных одноэлементных массивов и передаю их в функцию/метод.
А я смотрю вы тут #-холопы все какие-то зашоренные сидите. Склонитесь же перед Си-господином.
ну туплы
Tuple<>, они же кортежи
https://www.nuget.org/packages/System.ValueTuple/
Делаются на коленке на любом языке где есть дженерики
>Ну так-то goto иногда удобно.
настолько редко это иногда что приходится записывать эти случаи в красную книгу.
Постоянно используется. В нормальных местах даже ебут за его отсутствие там где нужно.
>А мне надо несколько, притом разнотипных. Вот я и объявляю несколько разнотипных одноэлементных массивов и передаю их в функцию/метод.
Ты ебанутый? Чем тебе Tuple (кортеж, уточнение для одаренных) не угодил? Что за тупейший дрочь с массивами размерностью в один элемент? Учись делать вещи правильно сразу же, а то потом будет тяжело переучиваться
>Я - не вы, чтобы по говнокурсам учить. Я в шараге учил, ну и сам в основном.
>Склонитесь же перед Си-господином.
Т.н. "Си-господин", c богатым опытом программирования в целых ДЖВА(!!!) проекта lab1|lab2, которому хватает ума чтобы делать все, кроме того что ему советуют (а именно использование Tuple/специальной структуры/ref-out), предлагаю Вам вернуться в Вашу проф. среду и в ней и остаться, коли Цэ Решетка не удовлетворяет Вашим изысканным требованиям
так толсто, что аж тонко
> По сути зарплата джуна в мелкоконторе. И нахуй нужен такой фриланс?
Ну там ебать будут за эти деньги. Я же не смогу играть на работе в пое
>чтобы делать все, кроме того что ему советуют (а именно использование Tuple/специальной структуры/ref-out)
Ты жопой читаешь или у тебя память девичья "кому дала не помню" забыл, что тремя постами выше было?
>>58572
>>ref, out
>Ну похоже это то что надо.
>>Кортежи
>Не взлетели. Может из-за того что у меня вижуал студия 2013 старая?
>целых ДЖВА(!!!) проекта lab1|lab2,
Нибамбит что у кого-то есть вышка, а у тебя нет?
>Не взлетели. Может из-за того что у меня вижуал студия 2013 старая?
всё. бросай. если у тебя не взлетают вещи которые, ну ок нет поддержки редактора для краткого синтаксиса, но в полном это просто примитивные дженерик классы/структуры, то значит тебе нужно еще 10 высших.
В С/С++ так. А это аргумент.
Вы же тут все так любите вашу модную инкапсуляцию. Вот это оно и есть, хоть и не ооп. Я создаю блок { }, объявляю там свои переменные и развлекаюсь с ними как хочу. Почему я должен согласовывать их имена с остальным кодом?
>Я же не смогу играть на работе в пое
Так ты и сейчас не можешь. Ты 30 часов за неделю потратил на работу, это практически и есть стандартная рабочая неделя (если из неё вычесть всяческие проебы времени).
>В С/С++ так. А это аргумент.
Аргументация "В моем языке так, хуле во всех остальных не так" - это сильно.
>>59474
>инкапсуляцию
Она тут с какого бока?
>>59474
>Почему я должен согласовывать их имена с остальным кодом?
Потому что гладиолус
https://metanit.com/sharp/tutorial/2.18.php
>в языке <name> вот так, а значит должно быть везде так
ну и пиши на языке <name>, какая проблема то. Ведь там есть привычное синдромоутятное
>Ты жопой читаешь или у тебя память девичья "кому дала не помню" забыл, что тремя постами выше было?
>ну ref-out подходит но все равно не буду их использовать.
"Зачем мне специальные конструкции конкретного ЯП которые как раз были созданы под моего рода нужды если можно ебаться с массивами?"
>VS 2013
Установить поновее ума нехватает или что? Слишком много кнопок надо нажать чтобы это сделать? Ты бы еще использовал самую первую версию дотнета/шарпа и говорил бы "ой, а почему у меня нету дженериков? Си Шарп говно что ли? Мда, а вот в крестах...". Даже если у тебя какая то острая необходимость ввиду чего-либо использовать только 13ую студию, у тебя есть еще целых два варианта решения своей проблемы.
>Нибамбит что у кого-то есть вышка, а у тебя нет?
Интересное конечно предположение, жаль только ошибочное. То был жирный небольшой намек на то, что ты делал по учебе и близко не стоит к тому как на самом деле пишут код сейчас на Си/Си++. Но зато да, ты определенно теперь знаешь как работают указатели, эт ты молодец. Можешь гордиться, только не зазнавайся.
>Нибамбит что у кого-то есть вышка, а у тебя нет?
Ты тот чел, который собирался делать одноэлементные массивы? Вышка чего у тебя? Клоуна?
>Какая документация, о чём ты? Я софтину почти для собственных нужд пишу.
Вот ты даже не понимаешь значения документации. Каким боком "для себя" оправдывает её игнорирование? Фразы "для себя" и "у нас не экзамен" используют только опущи с тремя классами образования. Для себя делают хорошо, но у долбоебов принято для себя делать спустя рукава.
>Я - не вы, чтобы по говнокурсам учить. Я в шараге учил, ну и сам в основном.
Еще хуже. Если в шараге такому учат, то там явно отсутствует контроль качества. Инфоцыган можно хотя бы в интернете хуями забросать и понизить им рейтинг, а твой говновуз закрыт от внешнего взора, и кто выходит из него — те кончи с ЧСВ, не отдающие отчета в своих действиях.
Но я думаю, что ты просто тролль
Если я привязываюсь к объекту типа Freezable, то изменение его свойств во вьюхе, автоматически обновляет все остальные привязки к этому объекту, если они были.
Но если я привяжусь к свойству (не важно какого типа) через конвертер, который в результате конвертации возвращает экземпляр Freezable объекта, то попытка во вьюхе изменить его свойства, не обновляет привязки.
Причем я пытался привязать к результату конвертации два контрола, и если я в одном контроле меняю содержимое Freezable объекта, то другой контрол это фиксирует. Но вот у самого конвертера не срабатывает метод ConvertBack, и не происходит изменение свойства во вьюмодели.
Почему?
работай с биндингами из кода и все поймешь....
....поймешь что нихрена не понять как оно устроено
Потому что биндинг это не цепочка "источник - таргет", а просто один биндинг. И если тебе нужно прервать одну цепочку то ты не можешь ибо нет никакой цепочки. Ты рушишь весь биндинг сразу.
Понять где там источник где таргет....сам черт ногу сломит.
> Как сделать так, чтобы при перерисовке одного слоя, остальные не перерисовывались
Меняю на этом слое цвет одной точки на прозрачный, твои действия?
я не он, но вычислить затронутые слои и их перерисовать.
Если я в UI сделаю один элемент прозрачным, разве тот, что находится за ним будет перерисован? Он же не изменился.
Нижний слой может и не изменится, но станут видны те его элементы, которые раньше скрывал верхний слой. Конечно же, их нужно теперь рисовать. Самый простой способ - перерисовать нижний слой и поверх него уже верхний. Но загвоздка в том, что у нижнего слоя тоже могут быть прозрачные элементы, за которыми видно цвета с ещё более низких слоёв, так что просто запросить цвет из одного нижележащего слоя не получится, будет по меньшей мере итерация до самого низа, и это на каждую точку с альфа-каналом меньше 255, причём надо ещё и учитывать разные эффекты смешивания цветов.
Может, это можно как-то оптимизировать, если перерисовка всех слоёв - супер дорогая операция (т.е. реально возникли проблемы производительности, а не просто теоретические рассуждения). Но для начала надо оценить, насколько дешевле будет вычислить все перекрытия и подготовить "дифф", тут попутно и другие нюансы могут возникнуть. Похожую проблему решают в 3D-графике с Z-buffer, наверняка там есть какие-нибудь трюки, чтобы работало быстрее.
Охуеть простыня получилась
Какого хуя там дедлок на дедлоке?
Еще и это. Типа, блядь. Код-то не я писал, а мне - вычесывать это.
Короче. Да.
Десктоп - могила. ВЕБ - сила.
>Какого хуя там дедлок на дедлоке?
подключи Fody ConfigureAwait и вычесывай в обратную сторону
еще можешь взять JoinableTaskFactory от разрабов студии но на самом деле и без него все норм
дык я и предложил. не перезванивать.
обновлять все слои на каждый чих это тупо. Взять тот же WPF - ему тыща лет, но даже он не обновляет то, чего не видно.
Думаешь, в вебе не бывает аналогичных проёбов с асинками? Ты просто мало веба видел.
> обновлять все слои на каждый чих это тупо
В глаза долбишься что ли?
Все слои != выделенные слои
Ну. МБ дело в том что в вебе я один работал.
За все время работы в вебе - всего один дедлок был. А тут - рил, буквально на каждом шагу.
Или еще веселей, не в том потоке обновил визуалку - КРАШ, нахуй. Не в том потоке обработал - КРАШ, нахуй.
Короче. Мне как-бы и нравится что не просто жсоны гоняешь, а КАК В КНИЖКАХ, ОРХЕТЕКТУРА, ВСЯ ХУЙНЯ. Но чет выглядит это все оч странно.
Хм, я думал, что нижний слой хоть и не виден, но хранится в памяти видеокарты. И при формировании итогового изображения которое выводится на монитор, все хранимые в памяти изображения отдельных элементов просто последовательно накладываются друг на друга и отрисовываются и выводится результат. Я не прав?
Вообще планирую с плюсов перекатиться в С#
Тут есть аноны кои проделали подобный трюк, какие подводные? Работу найти сложнее?
Проделывал.
Подводные - надо перестать писать говнокод. Больше людей понимают, что ты пишешь, а потому могут и спросить. Много чего учить надо. За велосипеды дают пиздюлей.
Работу найти проще. Платят, в среднем, больше.
>Много чего учить надо. За велосипеды дают пиздюлей.
Можно поподробней про эти два момента?
кстати я планирую в мобильную разработку, одобряешь?
блять почему?
Ну буквально постов 20 выше был чел, который в C# искал аналог указателей C++ для передачи параметров в метод и пришел к решению заворачивать каждое значение в массив. За такое в C# сообществе стреляют в упор, потому что есть специальные вещи для таких задач.
Какие книжки посоветуете для начала?
Или мне стоит учить только то, что требуется в вакансиях на ХХ для стажеров/джунов? Как адекватно это воспринимать, если количество необходимых условий или навыков "слишком" много/мало в вакансии?
Нужен отдельный ноут с линуксом?
Поступил на заочку околопрограммисткую, т.к уже заканчивал магу по другой специальности. Диплом и 2 статьи пилить... по ит для меня это новое и выглядит довольно странно( хотя и в теплотехнике формул хватало из книжек 20-50 летней давности)
мне 31
>Хочу учить с# вначале для десктопа, бекэнда, а потом перекатиться на разработку игорей
Звучит как "хочу начать учить сразу две разные профессии, чтобы потом перекатиться в третью". Это все разные специализации, требующие разных знаний. Там хорошо если процентов на 30% идет пересечение и переходя из одной в другую приходится дофига чего забывать и учить новое.
>Какие книжки посоветуете для начала?
Албахари
>>60857
>Или мне стоит учить только то, что требуется в вакансиях на ХХ для стажеров/джунов?
Выбираешь нужное направление, ищешь более-менее нормальный роадмап по нему и учишь. На вакансии ориентируешься уже когда хоть какой-то опыт будет.
>>60857
>Нужен отдельный ноут с линуксом?
Нет. Хватит виртуалки или wsl.
Для веба знание линукса будет в плюс.
>>60857
>Поступил на заочку околопрограммисткую,
В первую очередь на учебе нарабатывай связи и выходы на стажировку/практику. Все остальное вторично.
>для десктопа
не трать время.
сразу выбирай либо бэкенд либо игры.
Среди них очень мало пересечений между друг другом.
а причем тут зарплата, если работы не найдешь.
Смотря как использовать видеокарту. Если делать простую рисовалку 2D-графики на каких-нибудь винформах, видеокарта не узнает ни о каких слоях, для неё будет тупо готовая текстура, которую надо отрендерить, а все вычисления слоёв будут делаться на CPU. А можно через OpenGL/Vulkan/DirectX создать 3D-сцену с несколькими прямоугольниками по одному на слою, к ним уже привязать содержимое соответствующих слоёв, навесить пачку шейдеров, и тогда всеми вычислениями будет заниматься видеокарта, которая сама волшебным образом поймёт, что нужно перерисовывать, а что не нужно, а работать будет быстрее.
![image.png](https://2ch.life/pr/thumb/3218902/17251369922500s.jpg)
Прям видно, что составляла хрка
Спасибо за ответ, мне бы и в голову не пришло смотреть в сторону 3д графики для реализации подобного. Кем ты работаешь, если не секрет, что такими специфическими знаниями обладаешь?
Я всего лишь джавист-бэкендер, который ненавидит джаву. Никаких специфических знаний у меня нет, просто иногда изучаю всякое из интереса.
>Албахари
Там в общих чертах, лучше на инглише?
Я понимаю текст, но не могу уверенно на языке говорить.
> Выбираешь нужное направление, ищешь более-менее нормальный роадмап по нему и учишь. На вакансии ориентируешься уже когда хоть какой-то опыт будет.
Опыт разработки?
Что мне говорить... когда я не работал уже 1.5 года. А что в первый раз по другой профе?
> Нет. Хватит виртуалки или wsl.
> Для веба знание линукса будет в плюс.
Хм. Может есть список вещей, которые нужно сделать или по необходимости это всё потом устанавливать/изучать?
> В первую очередь на учебе нарабатывай связи и выходы на стажировку/практику. Все остальное вторично.
Да я хз если честно. Одногрупники(всего 5 штук) занимаются php или 1с-битрикс. И разговаривают неохотно. Они уже работают по профе, т.к бакалавра уже проходили, либо в ип работают кабанычем.
Или преподов по этому вопросу подергать?
>>61062
> сразу выбирай либо бэкенд либо игры.
> Среди них очень мало пересечений между друг другом.
Значит игры... но это мне придётся ориентироваться на запад сразу?
Или есть какая работа и в РФ?
ладно бы жава, мобилки, шарп, питон - ну чтобы покрыть все направления, авось куда то устроится, начать поднимать бабло и уже тогда учись куда хочешь.
с++ то зачем. тонну времени потратишь
какая же дурная капча. для решения ее с помощью ботов самая простая )))
> ладно бы жава, мобилки, шарп, питон - ну чтобы покрыть все направления, авось куда то устроится, начать поднимать бабло и уже тогда учись куда хочешь.
А как же конкуренция? Всё кроме шарпа перенасыщены... хотя тот же шарп, слышал, увядает
Тут все зависит от места жительства (хотя ковид немного подправил ситуацию в правильное русло).
Я в свое время вообще с руби начинал, потому что брали без знания вообще (ну то есть приходишь и говоришь - я котик у меня лапки и я ничего не знаю) и платили со старта 800 пока тебя обучают.
Все относительно. Вон тот же руби как по мне загнил давно, но люди работают и получают очень даже хорошо.
Так что многое зависит от что оно, где оно и откуда бабки берет.
А щас меня десктоп кормит. Причем кормит уже больше 10 лет. Но это не значит что на десктопе "пошел и нашел работу".
Жаль курсов бесплатных нет по тем прогам. На сайте трудоустройства по безработице смотрел - там тоже 1с один. А так бы сходил для ознакомления.
Ладно, пока Албахари скачал.
По английски новые термины непонятны, думаю разберусь
посмотрел вакансии
мде, джуны никому не нужны
ну разве что этим
"На данный момент наш проект не приносит дохода, поэтому оплата за работу не предусмотрена."
ну или я не знаю где искать
Значит вкатываться нужно было в 2014 году? Я нихера ничего не понимал в это время
Мне было... 20 что-ли
Думал такой буду проектировщиком, а как попал на работу в 25 - охуел с того насколько я там не нужен и это ужасно скучно для меня
Зато есть БАЗА. Чего не скажешь о наличии базы с ИТ
https://www.flenov.info/roadmap/web
пока ты ищешь волшебные уроки/курсы - ничего не выучишь. так и будешь искать. Потому что
а) мозг ищет волшебную таблетку
б) у каждого свое восприятие. Даже когда станешь спецом, то посмотри ролики для начинающих по любым темам - удивишься как 90% "непонятно вещают хрен научишься"
учиться нужно в работе. Прочитал по диагонали книжку или статьи плевать какие, хоть на метаинит и вперед делать что то. Спрашивать, гуглить, переделывать - так приходит понимание и закрепление.
Так что если хоть что то умеешь - сразу начинай писать рабочий проект. Пусть даже ты его выбросишь или 100 раз перепишешь.
забыл добавить главное - найди наставника. Гуглить конечно здорово, но быстрый фидбек "тут не так а так" просто бесценен. Ибо перебирать варианты "а можно закодить так" можно, но долго.
нет. просто полиглот
все что используется - обучается
все, что не используется - забывается.
концепции и парадигмы важнее знания языка, а они нарабатываются только в реальных проектах.
проблема в поиске реальных проектов, это да. Ибо ненужное писать лениво.
>Это в интернете если только. Или за деньги?
без понятия где. знал бы, сам использовал бы, а не тратил бы время на гугление.
и он не должен тебя учить. Должен лишь быстро отвечать на вопросы, обсирать твой код и подсказать направление или немного показать пояснить.
![2024-09-0119-20-44.jpg](https://2ch.life/pr/thumb/3218902/17252080188710s.jpg)
>new EventHandler<SomeEventArgs>(OnSomeEvent);
А как это используется, если ни на одно событие не подписаться дженерик- EventHandler-ом. Взять к примеру PropertyChanged в INPC. Выдается ошибка
>Не удается неявно преобразовать тип "System.EventHandler<TEventArgs>"
Или я должен создавать свой делегат на основе EventHandler<TEventArgs>?
это:
>typedSource.PropertyChanged += new EventHandler<TEventArgs>(OnSomeEvent);
выдает ошибку
>Не удается неявно преобразовать тип "System.EventHandler<TEventArgs>"
Как это исправить?
вместо TEventArgs должен быть конкретный тип.
Как по твоему источник события должен кидать само событие если у него типа нет.
>Там в общих чертах, лучше на инглише?
У Албахари есть два типа книг.
Первый - краткий справочник по языку. Просто выжимка страниц на 300. Очень удобна например перед собесом за часик пролистать и освежить знания. Или вспомнить как работает фича которой не пользовался некоторое время.
Второй - полный справочник на овер 1000 страниц. Там уже все подробно расписывается, с примерами и пояснениями.
Книга актуальная и постоянно выходят новые версии, последняя по 12-му шарпу.
Оригинал на английском, есть актуальные и неплохие переводы на русский. Читается на том и на том языке нормлаьно и легко.
>Опыт разработки?
>Что мне говорить... когда я не работал уже 1.5 года. А что в первый раз по другой профе?
Ну а что говорить. Тут стандартные два стула. Либо честно говоришь, что не работал, а учился/дрочил/болел, либо волчишь и рассказываешь про несуществующий опыт работы.
Судя по твоим вопросам - второй вариант ты не потянешь, поэтому - упарывайся в обучение и старайся за это время создать какой-нибудь учебный прект и вылизать его до такой степерни, чтобы было не стыдно предъявить как хоть какой-нибудь опыт.
>занимаются php или 1с-битрикс
Ну хреново, чо. Но даже у них хоть какой-то опыт есть и их можно поспрашивать про изнанку индустрии (безотносительно языка)
>Или преподов по этому вопросу подергать?
Дергать всех до кого дотянешься, прям доебывать.
>Значит игры... но это мне придётся ориентироваться на запад сразу?
Я все-таки посоветовал бы тебе веб. Ты не геймдев разработчик. Это сразу видно.
но все же есть региональные предпочтения для языков это факт.
суммарно по миру вроде много, а в твоем регионе ( локализации) может быть беда бедо
![2024-09-0119-55-38.jpg](https://2ch.life/pr/thumb/3218902/17252098248370s.jpg)
>Как по твоему источник события должен кидать само событие если у него типа нет.
Он указан в моем классе. Да даже если указать явно, то получается пикрил
>мде, джуны никому не нужны
Джуны нужны. Просто в нынешней парадигме, джун - это не тот, кто ничего не знает и только учится. А уже готовый специалист пусть и с небольшим опытом.
Ты пока даже на стажера не тянешь, т.к. и на стажировку предпочитают брать людей людей с более-менее нормальным пониманием темы.
я хз что там у тебя. ты нас обрезками кормишь
обычно ожидается
typedSource.PropertyCHanged-=OnSomeChanged
и вообще, бросай ты эту делегатную недохрень если для себя пишешь. Юзай lifetimes
>а в твоем регионе ( локализации) может быть беда бедо
В каком "твоем"? Ты в африке что ли жевешь?
![изображение.png](https://2ch.life/pr/thumb/3218902/17252111324230s.jpg)
В абтрактном любом. В какой то стране могут преобладать одни вакансии, а в другой другие. А еще либо нужно знание языка (обычного которым глаголят) или не нужно.
>>61726
ну я видел твой скрин. И значит мне не хватает инфы. (не в последнюю очередь что я просто пишу += и -= метод и не выделываюсь
и даже если создаю руками хендлер то потом его же инстанс и отписываю, а не создаю его еще раз (за что тебя и бьют по рукам)
В примере MDSN на тему слабых событий
https://learn.microsoft.com/en-us/dotnet/desktop/wpf/events/weak-event-patterns?view=netdesktop-8.0
есть такие строчки
typedSource.SomeEvent += new EventHandler<SomeEventArgs>(OnSomeEvent);
Я просто не пойму цель этой строчки. Используется дженерик хендлер, явно претендующий на универсальность, но не работающий со 100% всех событий. Я не понимаю что это и как это использовать.
>и вообще, бросай ты эту делегатную недохрень если для себя пишешь. Юзай lifetimes
У меня есть проблема. Я хочу сделать конвертер значений, который при помощи рефлексии преобразует свойства объекта в условный словарь (кастомный, Freezable), чтобы на стороне XAML автоматически выводились данные объекта. Короче, хочу сделать что-то вроде окна свойств в вижуал студио. Потому что сейчас для каждой модели надо вручную собирать свою вьюху в XAML.
Но проблема в том, что в случае с привязкой к INPC модели, при изменении свойств со стороны модели, не идет обновления привязки и не срабатывает конвертер. И тут два варианта (по моему неопытному мнению): либо INPC заменить на Freezable, либо прямо из конвертера подписаться на PropertyChanged. Оба решения максимально дурацкие, и я думаю, как это решить иначе, но если подписаться из конвертера на PropertyChanged, то это создаст жесткую ссылку и не отпустит вьюху. Я пытаюсь сделать мягкое событие. Вот.
> >Там в общих чертах, лучше на инглише?
> У Албахари есть два типа книг.
> Первый - краткий справочник по языку. Просто выжимка страниц на 300. Очень удобна например перед собесом за часик пролистать и освежить знания. Или вспомнить как работает фича которой не пользовался некоторое время.
> Второй - полный справочник на овер 1000 страниц. Там уже все подробно расписывается, с примерами и пояснениями.
> Книга актуальная и постоянно выходят новые версии, последняя по 12-му шарпу.
> Оригинал на английском, есть актуальные и неплохие переводы на русский. Читается на том и на том языке нормлаьно и легко.
На рутрекере 10 нашёл только
Поищу ещё
По полочкам мне нравится
> Судя по твоим вопросам - второй вариант ты не потянешь, поэтому - упарывайся в обучение и старайся за это время создать какой-нибудь учебный прект и вылизать его до такой степерни, чтобы было не стыдно предъявить как хоть какой-нибудь опыт.
> Ну хреново, чо. Но даже у них хоть какой-то опыт есть и их можно поспрашивать про изнанку индустрии (безотносительно языка)
Даж хз... не хочу там оставаться
Да. Первое и сказал, когда пришёл на собес. А там битрикс. Потом подумал лучше подучить и в другой город. Т.к в моем городе кроме 1с ничего нет
Тупой вопрос... а волки от слова walk?
> Дергать всех до кого дотянешься, прям доебывать.
Спрашивал, работы никакой не предлагают кроме этих же коллекторов или 1с(редко)
> Я все-таки посоветовал бы тебе веб. Ты не геймдев разработчик. Это сразу видно.
Ладно.
А можешь объяснить как ты это понял?
>>61711
Также про Варкрафт говорят. Жду его перезапуск. Даж интересно что микромягкие сделают с ним после 2030
>typedSource.SomeEvent += new EventHandler<SomeEventArgs>(OnSomeEvent);
это создается ЯВНО делегат указывающий на твой метод.
портянку с new можно не писать ибо за тебя ее напишет компилятор (сахар такой)
И нет тут никакого дженерик хендлера. не путай open generic и closed generic
Есть общий делегат EventHandler<T>
и вот он должен иметь тот же тип что и событие, которое, в свою очередь такой же делегат.
>либо
либо объявить подписку с пропертчиченджед.ехплисит и обновлять ее вручную когда посчитаешь нужным
или Observable словарь. или взять готовые пропертигриды где народ уже сам с этим намучился
>Также про Варкрафт говорят. Жду его перезапуск. Даж интересно что микромягкие сделают с ним после 2030
Каким образом Microsoft относятся к Варкрафту, если это игра от Близард? Ну и если уж говорить о перезапусках старых стратегий, то как раз таки Майкрософт - это те кто ебут на этом поприще всех остальных. Я имею в виду серию Age of Empires Definitive Edition, и готовящуюся Age of Mythology Retold. Такого качества перезапусков RTS ни у кого пока не было.
>>61747
>А можешь объяснить как ты это понял?
Я х.з. как это нормально словами объяснить, но для разработки в геймдеве нужно определнный склад ума иметь. По крайней мере ты не задавал бы вопросы "какую мне книжку почитать", а сидел бы сейчас и либо какой-нибудь движок ковырял, либо внутренности какой-нибудь игры, изучая язык просто экспериментируя в стиле "так сейчас вот тут поменяем и запустим. Ага значит вот эта штука позволяет запускать кусок кода несколько раз в цикле" и т.д. Тебе просто должно быть настолько в кайф ковыряться в кишках игор (а не играть в них), что это само по себе дает стимул изучать язык, как инструмент позволяющий это делать.
Если ты даже и сможешь выучиться и вкатиться в геймдев, то очень быстро поймешь, что это нифига не то, что ты себе представлял и там дичайшая потогонка, выгорание, низкие зарплаты и т.д. И нормально там живется только таким товарищам которых я выше описал.
>Тупой вопрос... а волки от слова walk?
Волки от слова "волки". Те кто пиздит в резюме и указывает там несуществующий опыт работы.
>пропертигриды
У меня WPF. Знаю, что есть и для него, но редко в таких штуках есть контроль.
>пропертчиченджед.ехплисит
Можно подробнее? У меня была идея внутри вьюмоедли подписаться на PropertyChanged модели и оттуда вызывать PropertyChanged вьюмодели. Но это может привести к зацикленности.
>Observable словарь
Он отображает только изменение итемов, а если у итемов меняются свойства, то словарь будет молчать. Нужен Freezable, но использовать его для моделей и вьюмоделей вроде как зашквар.
>Тупой вопрос... а волки от слова walk?
Был какой-то то ли блог, то ли чат, где автор учил вкатунов как устроиться на работу любыми доступными способами. Называл коммьюнити волками, ну а способы заключались в пиздеже эйчарам и круговой поруке.
Кстати, до этих волчар, на дваче в 3d-разделе точно были треды от анона, который предлагал объединиться и зарегать фейковую контору, поделать совместные проектики для артстанции и насрать опыт себе в трудовые книжки. Идея тогда не воплотилась — подумали, что ОП-хуй пытается эксплуатировать анонов. Но дело его живет и заразило собой IT сектор.
у биндингов есть UpdateSourceTrigger=Explicit который позволяет вам вызывать обновление источника когда вам угодно. Иногда даже приходится использовать.
вот как то делал DoubleTextBox. чтобы туда можно было ввести только числа и разделитель и замахался бороться с разделителем который летел на source и все там ломал. Не помню точно, вроде.... если у тебя число в текстбокс 49.9 и ты удаляешь и получается 49. то конвертер конечно превратит это в 49 дабл, но тут же обратно прилетит 49.0 и засрет тебе тексбокс.
пришлось мудрить целый огород
https://pastebin.com/yk6vtKP7
>Не помню точно, вроде.... если у тебя число в текстбокс 49.9 и ты удаляешь и получается 49. то конвертер конечно превратит это в 49 дабл
Да, у меня было такое.
>UpdateSourceTrigger=Explicit
Я вроде этот Explicit юзал, но для того, чтобы обновлять привязку текстбокса по нажатию Enter. Щас попробую.
Если я правильно понял, ты из тексбокса принудительно вызываешь обновление. Но ты же обновляешь только одно свойство, к которому текстбокс привязан, просто ты его обновляешь в нужной тебе ситуации. Но это не то, что мне нужно. У меня события свойств и так происходят.
Вот смотри, у меня во вьюмодели (на скрине не видно, это MyViewModel) есть свойство TestINPCClass (пикрил 1), как выглядит этот класс, изображено на пикрил 2 — там три тестовых свойства.
Если я привяжусь к свойству TestINPCClass.Color, и поменяю значение, то я вызову событие TestINPCClass.PropertyChanged. Но я не вызову событие MyViewModel.PropertyChanged, а именно последнее заставит обновиться мой конвертер. Мне Explicit никак не поможет.
А вот если бы свойство TestINPCClass содержало Freezable-объект, то изменение значенияTestINPCClass.Color, вызвало действия аналогичные MyViewModel.PropertyChanged
Если ты ещё не понял, я нюфаг в С#. У вас тут какие-то полные, краткие синтаксисы, поддержки редакторов, черти лысые. Без пол литра не разберёшься.
>>59700
>Зачем мне специальные конструкции конкретного ЯП которые как раз были созданы под моего рода нужды если можно ебаться с массивами?"
Придумал про меня хрень какую-то и остался доволен. Я нигде не говорил что отказываюсь от ref/out.
>что ты делал по учебе и близко не стоит к тому как на самом деле пишут код сейчас на Си/Си++
Откуда ты знаешь о моих знаниях о том как пишут код Си/Си++?
>жаль
Почему жаль? Жалеешь что вышку получил?
>>59959
>Вот ты даже не понимаешь значения документации. Каким боком "для себя" оправдывает её игнорирование? Фразы "для себя" и "у нас не экзамен" используют только опущи с тремя классами образования. Для себя делают хорошо, но у долбоебов принято для себя делать спустя рукава.
М-да? А моё потраченное время ты оплатишь? Ты на каждый свой пук документацию пишешь?
>Если в шараге такому учат, то там явно отсутствует контроль качества.
В шараге я как раз Си/Си++ учил а не #.
>>59968
Да, я видел. Спасибо.
>>59939
>Ты тот чел, который собирался делать одноэлементные массивы? Вышка чего у тебя? Клоуна?
Я делал одноэлементные массивы в отсутствии информации о ref/out и прочем. И как видишь сумел выкрутится и решить возникшую проблему. А всё почему? Потому что я - Си-господин с вышкой, а вы #-холопы после говнокурсов.
А вообще вы тут какие-то гиперчувствительные. Теперь понятно почему в ваш тред любят жабисты захаживать.
Привет >>59939 -клоуну!
ты идешь не туда.
никто не запрещает событиям работать во все стороны (главное отписку продумай)
Если у тебя псевдокод
rootVm.PropertySet { a: String, b: int}
и ты биндишь a и b, но хочешь чтобы при их изменении еще и rootVm знала об этом - ну так сообщи ей об этом прямо. Можешь выставить событие у PropertySet, на которое подпишется рутовая вьюмодель. Или она может подписаться на тот же INPC и реагировать как хочется.
для этого события и придумали. лишь бы с отпиской все было хорошо - у тебя это и weak event и "циклическая подписка не ведет к утечкам памяти", у меня lifetime, которые я рекомендую всем налево и направо.
> >Также про Варкрафт говорят. Жду его перезапуск. Даж интересно что микромягкие сделают с ним после 2030
> Каким образом Microsoft относятся к Варкрафту, если это игра от Близард?
Я про ммо. Стратежку вряд-ли кто то перезапустит
> Я х.з. как это нормально словами объяснить, но для разработки в геймдеве нужно определнный склад ума иметь. По крайней мере ты не задавал бы вопросы "какую мне книжку почитать", а сидел бы сейчас и либо какой-нибудь движок ковырял, либо внутренности какой-нибудь игры, изучая язык просто экспериментируя в стиле "так сейчас вот тут поменяем и запустим. Ага значит вот эта штука позволяет запускать кусок кода несколько раз в цикле" и т.д. Тебе просто должно быть настолько в кайф ковыряться в кишках игор (а не играть в них), что это само по себе дает стимул изучать язык, как инструмент позволяющий это делать.
Наверное я просто в них так не ковырялся никогда. Не возникало причин. Разве что приходилось по куче раз моды переставлять в том же морре. Да и какие то челы уже перетаскивают её на другой движок
> Если ты даже и сможешь выучиться и вкатиться в геймдев, то очень быстро поймешь, что это нифига не то, что ты себе представлял и там дичайшая потогонка, выгорание, низкие зарплаты и т.д. И нормально там живется только таким товарищам которых я выше описал.
Но ради чего эта вся романтизация?
>>61776
Я патологически не могу врать, т.к чувствую себя неловко
Мне наверн будет тяжело... как и по всей жизни было. Считали бестактным некоторые
>>61799
Интересно. А ведь это понятие везде используется
Приходится делать какие-то маразматические проверки, что я не верблюд и не беру дважды одну и ту же ентити. Я уж молчу об ахуенном трай кэтче и роллбэке явном.
Что я делаю не так-то? Почему все так плохо?
Использую пик2. Памагите
Еще забыл добавить. Детач не убирает этот трек. Так бы просто попользовался и выкинул, но нееет. Тащи его везде.
Я честно сказать вообще не понимаю как этот механизм работает. Типа в некоторых случаях, бд просто перстает обновлятся, даже селект не идет. Руки вероятно кривые, но все же.
Да и я например не хочу отключать все эти отслеживания, а просто детачнуть один объект и аттачнуть его уже в другом месте. Не выкупаю, почему это не работает.
Типа ну нахуя-то же эту хуеверть сделали, возможно есть более разумное примение и обоснование ее существования.
Делаю веб приложение, в проекте есть уровень репозитория который взаимодействует с бд; уровень сервиса который взаимодействует с репозиторием и преобразует данные для отображения клиенту; и непосредственно контроллер который их возвращает со своей дополнительной логикой.
В чем суть - раньше я логику выносил в отдельный класс которые логически делил (класс-инициализатор, класс который отслеживает куда пользователя нужно редиректнуть и загрузить ему нужные данные и т.д.) и жил я без этих выше описанных слоев (просто с MVC архитектурой).
Сейчас при попытке вынести основную логику в отдельный "utility" класс я передаю в методы просто интерфейс сервиса (да, я заранее понимал что это уже какое-то ебланство) если быстро делать на клиенте какие-то действия - кидает EF исключение database context is already used.
Варианты как это пофиксить которые я сейчас вижу:
- Вынести всю логику в контроллер.
Подводные - очень большой контроллер в котором будет как минимум овер 4к строк, когда реально там нужно не более 500.
- Сделать для логики отдельный сервис.
Подводные - копипаст кода, т.к. я не могу из сервиса вызвать другие сервисы.
- Попробовать заинжектить сервис менеджер в текущий "utility" класс в котором не передавать интерфейсы сервисов через аргументы, а обращаться к уже внутреннему свойству класса.
Подводные - я пока хз можно ли так делать + не уверен пофиксит ли это обращение к dbContext'у из нескольких мест.
Как вообще правильно такое делается в этих ваших тырпрайзах?
>> в проекте есть уровень репозитория который взаимодействует
Подумай вот о чем - EF это уже и есть репозиторий. Если хочешь йоба сервис для всего пили CRUD дженерик репозиторий, но тогда и юзай его везде как надо, но потом ты поймешь что EF делает тоже самое.
>> логику в отдельный "utility" класс
Ты че ебнутый? Utility классы нужны для всякой хуиты типа перевода даты из одного формата в другой, потому что долбоебы спроектировали фронт или для перевода ру текста в транслит и т.д.
>> Вынести всю логику в контроллер.
Гугли "толстые тупые контроллеры", так делают "необучаемые макаки с 50 лет стажу потому что у них так дед дела и они так будут делать".
>> - Сделать для логики отдельный сервис.
Самая адекватная идея.
>> Как вообще правильно такое делается в этих ваших тырпрайзах?
Описал сучность
Создал к ней сервис
Создал контроллер
Заинъектил этот сервис в контроллер
>> с++
уж лучше в Rust вкатываться, от крестов всею плюются, потому что заебало ходить по одним и тем же граблям, каждый ебучий раз
> Подумай вот о чем - EF это уже и есть репозиторий. Если хочешь йоба сервис для всего пили CRUD дженерик репозиторий, но тогда и юзай его везде как надо, но потом ты поймешь что EF делает тоже самое.
Нет, ef это ef. Он не решает задачу абстрагирования от уровня хранения данных. С ним ты никак не мокнеш данные для тестов например.
>> - Сделать для логики отдельный сервис.
>Самая адекватная идея.
Как мне правильно дергать другие сервисы в этом сервисе? Инжектнуть их?
Немного разобрался. Обычно такое возникает, если какой-то контекст тянет из бд кортеж, который есть в другом контексте.
Конечно вообще не удобно, что есть несколько разных контекстов, с разными бакетами. Но по крайней мере понятен источник проблемы и как ее решить. Впрочем в идеале бы вообще убрать деталь реализации в виде ебаного детача.
>> Как мне правильно дергать другие сервисы в этом сервисе? Инжектнуть их?
Возможно проще будет собрать отдельный сервис куда заинъектить все нужные сервисы, это конечно может вызвать доп телодвижения в виде сущностей\репо, но это лучше чем нарваться на circular dependency в самый неожиданный момент и ебаться его разруливать, а это в готовой приложухе бывает не просто и как правило заканчивается дерганием в методе нужного сервиса через инстанс контейнера.
>> Нет, ef это ef. Он не решает задачу абстрагирования от уровня хранения данных. С ним ты никак не мокнеш данные для тестов например.
Ок, не сам ef, а объект MyFavoriteEntityContext
какая основная фича раста? - не допускать утечек памяти когда аллоцировал, но не освободил.
ну и попутно другие типа переполнение буфера
...спросил он в шарпотреде
откуда нам знать....подумал любой шарпист. Мы лишь знаем что си говно, собственно поэтому мы и выбрали шарп.
Я думал вкурсе, если его предложил. Ну ладно
>Это если под плюсами подразумевается не "lab1.cpp"
И если выкинуть из головы желание пихать везде указатели
И вообще нахуй выкинуть из головы плюсы
>> А берут ли куда с растом в рф?
Сейчас не берут, просто когда начнут брать у тебя будет 0 опыта и ты никому нахуй не нужен будешь, как не будешь нужен со знанием крестов. Вот такие вот ножницы, выбирать тебе
Подскажите нубу, нужно написать небольшое кросс платформенное desktop приложение (windows + linux), основная суть в выводе графиков и диаграмм. Это можно сделать на c#, используя AvaloniaUI? Не хочется qt и плюсы трогать.
какой фреймворк сейчас актуален?
я вот скачал Rider там мне на выбор:
Blazor, Web API, Web App, razor какой-то, gPRC
а я вообще начал ASP.NET учить, но там уроки 2-3 годичной давности.
Может Web App(MVC) это и есть ASP.NET?
поясните неофиту за web пожалуйста
> какой фреймворк сейчас актуален?
ASP.NET.
> а я вообще начал ASP.NET учить, но там уроки 2-3 годичной давности.
Судишь об актуальности фреймворка по наличию васянских туториалов на русском?
> Может Web App(MVC) это и есть ASP.NET?
Нет.
делаю перекат
смотрю различные другие языки. ебать я в шоке от хаоса который твориться в индустрии, ну да ладно.
Пришел для себя к выводу что С# наиболее оптимальный вариант, т.к. кросплатформенность, развитый и разнообразный стек технологий, и можно ради это закрыть глаза на ебучий микрософт
какие еще варианты есть:
- вечная джава, хз чисто ментально туда не хочу, не знаю почему даже
- rust перспективен, но пока рановато
- Go что скажете за Go?, гугл же все таки
надеюсь я сделал правильный выбор, хотя в целом мне похуй
Да, с авалонией легко такой сделать, мельтитаргет с одним проектом под общую логику, и отдельные проекты под конкретные платформы будут. И какой-нибудь scottplot для графиков взять.
Раст и го абсолютно разные язычки. Один уходит с головой уходит в компайл тайм проверки, а второй в простоту.
>- Go что скажете за Go?, гугл же все таки
удивляет уродливый синтаксис этого говна. Про раст говорят что там инопланетный синтаксис, но на деле все наоборот. Такое ощущение что го исповедует принцип "а давайте сделаем чтобы не как у других, чтобы отличаться"
>я вот скачал Rider там мне на выбор:
>Blazor, Web API, Web App, razor какой-то, gPRC
Это не фреймворки, а шаблоны проектов. И, сюрприз, там под капотом везде будет ASP.NET даже у блазора.
>можно ради это закрыть глаза на ебучий микрософт
>что скажете за Go?, гугл же все таки
Я не понимаю каким образом в голове у людей складывается идея "майкрософт - плохо, гугл - хорошо". И то и то - злоебучие корпорации стремящиеся только к увеличению прибыли.
![2024-09-0318-04-14.jpg](https://2ch.life/pr/thumb/3218902/17253763396300s.jpg)
Или взять WeakEventManager. Я создал окно, и при изменении DataContext подписываюсь на PropertyChanged модели (пикрил). Метод TestModel_PropertyChanged срет в окно интерпретации каждый раз, когда я меняю значения свойств модели TestModel. Далее я закрываю окно, после чего вероятность отписки (о которой я сужу по сообщениям в дебаг) выглядит как чистый рандом.
Я могу это как-то связать с настроением GC, но я ради теста прождал минут 20 и порой изменений нет. Я создаю новое окно и тут же закрываю. Отписка от нового произошла мгновенно, а предыдущая осталась висеть. Вот по какому принципу это работает?
>Вот и думай.
чего там думать. Как GC проснется - так и почистит. Когда проснется? Когда захочет, да и то твоя ссылка может лежать во втором поколении, а до его чистки дело не дойдет. Памяти хватает, системе не нужно, GC не дергается.
>выглядит как чистый рандом.
те же самые правила. Окно умрет сразу конечно, но вьюмодель то про это не знаешь (если ей сам не скажешь) и продолжает принимать сообщения которые уже не нужны. Ну пока GC не проснется и не прихлопнет её тем самым вызвав отписку.
>могу это как-то связать с настроением GС
с ним и только с ним.
>Отписка от нового произошла мгновенно
0 поколение же. Чистится наиболее часто.
Поэтому лайфтаймы рулят
>Памяти хватает
А это сколько? Не хочу, чтобы мое приложение жрало гигабайт только потому, что памяти в ОЗУ хватает.
>Окно умрет сразу конечно, но вьюмодель то про это не знаешь (если ей сам не скажешь) и продолжает принимать сообщения которые уже не нужны.
Там два варианта. Один это через своего рода WeakEvent, внутри которого находятся мягкие ссылки.
А второй через WeakEventManager, но этот хранит обычные подписки, и его не особо рекомендуют.
>А это сколько?
ну дык ахез
"Сборка мусора возникает при выполнении одного из следующих условий:
...
Объем памяти, используемой объектами, выделенными в управляемой куче, превышает допустимый порог. Этот порог непрерывно корректируется во время выполнения процесса.
... "
но там есть нюансы
https://habr.com/ru/articles/754248/
>но этот хранит обычные подписки
все они хранят слабые подписки хз о чем ты.
обычные подписки хранят только....обычные подписки.
А поскольку Dispose паттерн дырявый как (цензура), то поэтому и используют слабые события. Хотя правильнее использовать lifetime-ы, но на момент изобретения WPF не додумались.
>все они хранят слабые подписки хз о чем ты.
Ну я имею ввиду это
>vm.TestModel.PropertyChanged += OnPropertyChanged;
Если мое окно подпишется таким образом, то оно не уничтожится никогда.
Нет, не просто. Я хочу WeakEvent или WeakEventManager использовать для своего конвертера значений (который я упоминал выше), а он не знает когда будет выгрузка контрола-родителя, в ресурсах которого он хранится. Либо в этот конвертер пихать ссылку на родителя, чтобы подписаться на Unloaded.
Я думаю, какой вариант выбрать, но чем проще, тем менее надежно. Либо заставлять модель создавать WeakEvent, либо заставлять представление передавать ссылку на себя. Либо обновлять свойство вьюмодели при каждом изменении свойства модели и тогда напрягать вообще всех, кто к этому свойству подписался. Либо для модели вместо INPC использовать Freezable. Либо городить лайфтаймы.
Но вот такого решения, чтобы без мороки подключить конвертер, который бы автоматически отслеживал изменения свойств модели (кроме мягких ссылок), пока не нашел.
>Капец ты жадный на инстансы
Инстанс чего? Контрола? Этот контрол может хранить в себе тяжелые данные, типа битмапов, и может быть элементом какого нибудь списка. У меня так приложение начинало жрать 300Мб.
>А вообще конвертер выгрузится вместе с контролом.
Если конвертер подписался на модель по принципу
>value.PropertyChanged += OnPropertyChanged;
то контрол не выгрузится, потому что в событии модели лежит ссылка на метод OnPropertyChanged.
>Контрола?
конвертера
>то контрол не выгрузится, потому что в событии модели лежит ссылка на метод OnPropertyChanged.
поэтом слабые события для INPC и придуманы. Ну да, будет вызывать еще некоторое время (вернее может вызывать) и что? гуи все равно уже ничего делать не будет, ведь контрол выгружен.
>гуи все равно уже ничего делать не будет, ведь контрол выгружен.
Разве контрол не будет висеть вместе с конвертером?
будет пока GC не скушает конвертер. но сам контрол не будет заниматься задачей рисования изменений.
К тому же никто не запрещает отследить в контроле выгрузку (unloaded / window.close ) и сказать конвертеру "прекрати обрабатывать события то есть отпишись от модели"
Ты читать то хоть умеешь или совсем хлебушек? Тебе прямо ссылку кинули где разъясняется как контекст видимости в шарпе работает.
То, что это не соответствует твоим ожиданиям - исключительно твои трудности.
>Конкретную аргументацию попрошу.
Потому что в твоей глупой конструкции нет практического смысла, но которая мешает другому сахарку, более полезному. Вот и вся аргументация.
Потому что вот так устроена жизнь. Ты либо строго придерживаешься правил и страдаешь как в C++, либо упарываешься развратом и содомией как в джава скрипте, либо пытаешься придерживаться правил, но иногда кладешь на них блот, чтобы жизнь была чуть слаще — это путь шарпа.
Помимо предоставленной выше статьи про "блоки кода", хотел бы упомянуть лямбда выражения, которые позволяют объявлять внутри себя локальные переменные:
> int i = 3;
> var useless = () =>
> {
> int i = 5; //локальная переменная с тем же именем
> };
Но ничего не мешает сделать и так:
> int i = 3;
> var useless = () =>
> {
> i = 5; //присвоение значения переменной, объявленной до блока
> };
т.е. если переменная не объявлена внутри блока лямбда выражения, то ее поиск начнется за его пределами (но не дальше области видимости функции). Почему так сделали? Ну если отбросить понятия и каргокульт, а вернуться к здравому смыслу, то для чего нам понадобятся подобные блоки внутри функции? Для многократного выполнения большого объема кода, и тогда становится понятно, что бессмысленная строгая инкапсуляция тут не нужна.
Кстати, работает так же как методы и с полями:
> int myValue = 5;
> int GetMyValue_A()
> {
> int myValue = 10;
> return myValue;
> }
> int GetMyValue_B()
> {
> return myValue;
> }
> Console.WriteLine(GetMyValue_A()); // вернет значение локальной переменной: 10
> Console.WriteLine(GetMyValue_B()); // вернет значение поля: 5
>Конкретную аргументацию попрошу.
Потому что в твоей глупой конструкции нет практического смысла, но которая мешает другому сахарку, более полезному. Вот и вся аргументация.
Потому что вот так устроена жизнь. Ты либо строго придерживаешься правил и страдаешь как в C++, либо упарываешься развратом и содомией как в джава скрипте, либо пытаешься придерживаться правил, но иногда кладешь на них блот, чтобы жизнь была чуть слаще — это путь шарпа.
Помимо предоставленной выше статьи про "блоки кода", хотел бы упомянуть лямбда выражения, которые позволяют объявлять внутри себя локальные переменные:
> int i = 3;
> var useless = () =>
> {
> int i = 5; //локальная переменная с тем же именем
> };
Но ничего не мешает сделать и так:
> int i = 3;
> var useless = () =>
> {
> i = 5; //присвоение значения переменной, объявленной до блока
> };
т.е. если переменная не объявлена внутри блока лямбда выражения, то ее поиск начнется за его пределами (но не дальше области видимости функции). Почему так сделали? Ну если отбросить понятия и каргокульт, а вернуться к здравому смыслу, то для чего нам понадобятся подобные блоки внутри функции? Для многократного выполнения большого объема кода, и тогда становится понятно, что бессмысленная строгая инкапсуляция тут не нужна.
Кстати, работает так же как методы и с полями:
> int myValue = 5;
> int GetMyValue_A()
> {
> int myValue = 10;
> return myValue;
> }
> int GetMyValue_B()
> {
> return myValue;
> }
> Console.WriteLine(GetMyValue_A()); // вернет значение локальной переменной: 10
> Console.WriteLine(GetMyValue_B()); // вернет значение поля: 5
>Кстати, работает так же как методы и с полями:
Ну так в спеках так и написано, что объявление переменных в области видимости кода перекрывает те, что были заданы в области видимости класса, но не те, что были заданы в области видимости метода. Поэтому поля и перекрываются.
И тащемта это нифига не инкапсуляция, а полиморфизм, если уж в термины ООП влезать.
>Ну так в спеках так и написано, что объявление переменных в области видимости кода перекрывает те, что были заданы в области видимости класса
Тогда это бы работало:
> int i = 3;
> {
> int i = 5;
> }
Каким нахуй боком это полиморфизм?
>Тогда это бы работало:
Схуя ли бы это работало, если int i = 3, это как раз контекст метода, а не класса.
В глаза ебусь. В теле лямбда выражения ты можешь перекрыть то, что было задано в области видимости метода — в этом отличие от блока кода.
MVC - это типа паттерн (теория)?
WPF - уже конкретная реализация этого паттерна на дотнет?
ты сравниваешь теплое с мягким.
WPF вообще не паттерн. это фреймворк для построения GUI.И вот он уже дружит с паттерном MVVM, который уже паттерн типа MVC только другой
спасибо за ответ
стало понятней
тогда если не сложно, можешь ответить ещё на один вопрос
вот я использую например в своем приложении пространство имен: System ну или там SystemData
я их подключаю в коде используя using
сами эти библиотеки я нашел в папке ... nuget
это CIL файлы как я понимаю.
В какой момент они конектятся к программе? Они вроде как находятся в CLR пространстве.
Т.е. в начале мой код на С# транслируется в CIL.
Затем уже CLR также линкует эти библиотеки к моему коду и затем все вместе в машинный код?
ну у тебя и вопросы. 99% это нафиг не нужно.
твои using и использование классов оттуда являются просто текстов в текстовом файле *.cs
А далее используя подключенную длл (неважно откуда) IDE может использовать метаинформацию о классах и прочем из этой сборки чтобы подсказывать тебе "тута плохо".
А потом уже компилятор будет использовать ту же инфу и запишет что для твоей сборки нужны вот те зависимые сборки и мол после их загузки появится то, что можно вызвать будет вот так. там оно все как то свяжется в рантайме и будет хорошо
из этого следует что даже в статически типизированном языке можно подгрузить в рантайме не ту сборку и получить "метод не найден".
![2024-09-0414-31-51.jpg](https://2ch.life/pr/thumb/3218902/17254496904800s.jpg)
ButtonClickEventManager наследует класс WeakEventManagerBase, у которого тип ButtonClickEventManager.
Что за странная рекурсия?
не "у которого тип", а "который параметризующий ДЖЕНЕРИК параметром заданного типа"
кстати, каноничный паттерн это - у него (наследник как дженерик параметр базового класса) даже свое отдельное название есть, которое не помню.
А я чет пытаюсь наследовать просто WeakEventManager<TEventSource, TEventArgs>, а мне пишет "не содержит конструктор, который принимает аргументы 0". Но других конструкторов и нет, да и все методы статические. Наверно это автор пытается обойти.
нет никакой связи между дженериками и конструкторами.
паттерн нужен когда родительские методы должны работать с дочерним типом.
Сделал две точки проверки токенов по гайду https://learn.microsoft.com/en-us/aspnet/core/security/authorization/limitingidentitybyscheme?view=aspnetcore-8.0#use-multiple-authentication-schemes
Все работает, я проверил с помощью событий в конфигурации, оба работают и жрут каждый свой токен.
Бида какая.
Разрабы не особо замарачивались и просто если один упал вызывают другие если есть и все, но у нас в проекте есть класс middleware своей который ловит контекст запроса и достаёт данные авторизации передавая HttpContext в наш собственный контейнер.
Так вот эта мидлваря ловит только ПЕРВУЮ попытку, если она провалена и мы использовали второй вариант, то она не вызывается и в итоге обосрамс.
Тут вот написано https://learn.microsoft.com/en-us/aspnet/core/fundamentals/middleware/?view=aspnetcore-8.0
Что все пользовательские мидлвари вызываются после всех .НЕТ приседаний, но почему тогда моя мидлваря вызывается сразу после первой аутентификации, а не после всех?
Какие есть варианты получения контекста до момента когда будет исполнен любой код и после всех штук в самом .НЕТ? Либо в чем я не прав?
ВСЕ мидлвари вызываются в том порядке в котором ты их нахуярил при билде приложения.
Вангую, что ты свою мидлварь поставил до того как аспшные отрабатывают.
![Screenshot20240904193421Chrome.jpg](https://2ch.life/pr/thumb/3218902/17254677337630s.jpg)
Я же тебе дураку даже дал ссылку на документацию. Пробовал изучать то на чем пишешь?
![image.png](https://2ch.life/pr/thumb/3218902/17254705532450s.jpg)
Читать, а не картинки смотреть ты-то сам пробовал?
Там прямо написано
> You have full control over how to reorder existing middlewares or inject new custom middlewares as necessary for your scenarios.
А может просто открыть исходники и посмотреть как оно там работает и действительно ли что-то реордерится?
Не. Это же пиздец как сложно.
Короче. Пошел нахуй. Мне таких пидорасов на работе хватате.
Все нашёл решение проблемы. Удалили из проекта все что было понаписано до меня для мидлварей и прочей архетуктуры и в фабрике контекстов использовал IHttpContextAccessor. Через него контексты получаются нормально.
Минус 5 классов и 300 строк кода. Плюс 4 строчки кода для получения контекста через аксессор.
Блять долбач ты обосаный. Там имеются ввиду кастомные мидлвари.
Все твои написаные тобой будут вызваны в том порядке в каком указаны ПОСЛЕ стадартных мидлварей. Также сами родные мидлвари должны идти в определённом порядке чтобы нормально работать.
Ещё раз для тупых ебанатов как ты. Всё твои мидлвари вызываются только после работы всех внутренних кишок. Никто тебе не даст выполнить твою хуйню посреди процесса авторизации.
Для А0 дауна ещё поясню.
Тебе английским языком пишут что существующие ты можешь как угодно менять порядок И добавлять по необходимости свои. Там ничего не сказано что они будут вызваны там где ты их сунул. Оно так не работает.
>кстати, каноничный паттерн это - у него (наследник как дженерик параметр базового класса) даже свое отдельное название есть, которое не помню.
Лол. Тоже постоянно пользуюсь таким и в дуже не ебу как этот паттерн называется.
>ПОЧЕМУ?
> "почему сделано именно так?"
Ну так иди и Хейлсбергу этот вопрос задай. Он еще жив и вполне может тебе ответить. А нам плевать. Мы знаем как это работает и не ебем себе мозг вопросами "а почему в С++ или Java по другому"
Тебе прямо сказали, что лезть в другой язык (даже родственный) со своими представлениями о том как должно быть - хреновый подход. Нет нигде никакого глобально правила, о том как и что должно реализовываться в языках. Каждый делает как хочет. Максимум что, можно под глобальные правила подтянуть - это полноту по Тьюрингу.
>В твоём посте тоже ответа на "почему сделано именно так?"
Буквально весь пост об этом. В глаза долбишься?
1. У тебя поля класса доступны методам класса. По этой же логике переменные метода доступны пространству блока кода.
2. Задач, когда блок кода юзает данные пространства метода значительно больше, чем задач, где надо запретить доступ.
>Ещё раз для тупых ебанатов как ты. Всё твои мидлвари вызываются только после работы всех внутренних кишок. Никто тебе не даст выполнить твою хуйню посреди процесса авторизации.
Делаем ставки сможет ли эта связка прожевать гигабит ипв6 пакетов
НО разве проверка obj as ISomeне не исключает этотого?
object? obj;
var someObj = obj as ISome;
if (serializableObj == null)
{
obj = 1;
}
obj.ToString();
Очевидная опечатка, спалил проприетарную часть которую пытался утаить, serializableObj имелось ввиду someObj.
У тебя ToString находится за пределами блока if. Компилятор не настолько умен, как ты думаешь. Система проверки видит, что присваивается какое-то значение, а какое — хз (может оно тоже null), поэтому выдает предупреждение.
Единственное, что понимает компилятор, это если бы в твоем блоке if стоял return. Ну или пиши со знаком "!"
> obj!.ToString();
если абсолютно уверен, что null не придет.
>НО разве проверка obj as ISome не не исключает этого?
У тебя какой-то бардак, даже если допустить, что это просто пример. Почему ты кастуешь к ISome, но присваиваешь 1? Это вообще разные типы, от чего и появляются проблемы. Кроме того, ToString() допускает возврат null, тогда зачем эти танцы с присвоением единицы? Но в реальности никто так не делает, соответственно и такой проблемы нет:
> string? result = obj is ISome someObj ? someObj.ToString() : string.Empty;
или так
> ISome some = obj is ISome someObj ? someObj : new Some();
> some.ToString();
Как только ты срешь в переменную разными типами, вот тогда и начинаются траблы. Ты вот даже вроде бы проверил obj, а снова срешь единичкой чтобы что? Чтобы снова проверять на валидное содержимое?
Я даже не знаю какой пример лучше написать, помтоу что я не понимаю, для чего ты кастуешь к ISome, вместо того, чтобы использовать object?.ToString().
МОЖЕТ БЫТЬ ты в блоке if хочешь реализовать кастомный конвертер, но тогда выглядит деструктивно, потому что ты меняешь obj, вместо того, чтобы формировать string (а лучше StringBuilder). Но даже в оверрайднутом ToString() не может быть проверки на null.
Пример настолько нелогичный, что даже не знаешь куда копать.
> string? result = obj is ISome someObj ? someObj.ToString() : string.Empty;
точнее даже так
> string? result = obj is ISome someObj ? someObj.ToString() : null;
Если obj null, то someObj тоже null, а значит ему будет присвоено не нулевое значение в блоке if.
>>64903
Понятно. Предполагал такое но не знал наверняка. Просто тогда какой смысл во всей этой хуерге с (не)зануляемыми ссылочными типами если ворнинги опять вручную давить, да еще под это дело корежить код.
>>64919
>>64921
>У тебя какой-то бардак
Может у вас, я кажется пару раз дал понять что это максимально краткий пример для выяснения языковой фичи, что за ним стоит не важно? Естественно там не 1 и не ToString, раз уж спалился речь идет о сильно кастомном сериализаторе которые может обрабатывать любой тип: простой, структуры\классы или специальный с интерфейсом у которого особая логика работы. Соответственно во внутрених методах при проходе по дереву свойствнужно разруливать было лы вообще начальное значение у свойства, было оно простого типа, структурой или интерфейсом и каждое из этих ветвлений требует своих действий.
>Просто тогда какой смысл во всей этой хуерге с (не)зануляемыми ссылочными типами если ворнинги опять вручную давить
Оно должно напоминать, чтобы ты случайно не забыл это сделать. Ну и как я уже писал, если ворнинги приходится подавлять, то возможно код сомнительный. Не сказать что всегда, но в большинстве случаев.
Единственное исключение, это ворнинги при инициализации, когда в конструкторе пытаешься задать дефолтное значение поля через свойство. И там нельзя просто поставить "!".
>Может у вас, я кажется пару раз дал понять что это максимально краткий пример для выяснения языковой фичи
Так в том-то и суть, что когда делаешь норм, то и она работает норм. А смысл обсуждать поведение фичи, когда код не норм?
варнинги много где приходится подавлять. Анализатор в шарпе весьма тупенький. Банально нет lateinit, многочисленные аттрибуты для контроля хрен пойми как вообще работают (смотришь сигнатуру словаря TryGetValue, копируешь для своих трагетов - не работает. Меняешь аттрибудт на противоположный - работает, ааааа)
Хотя лучше, чем никакого.
Пока ещё не приступал к задаче кста.
Так что
https://www.milanjovanovic.tech/blog/fast-sql-bulk-inserts-with-csharp-and-ef-core
Мнение мысли?
У него там тупо аддрэндж и сэйвчэнджэс. что может быть проще?
100% сои
delegate unmanaged[Cdecl]<WGPURequestAdapterStatus, WGPUAdapterImpl, sbyte, void, void> callback
</code>
Шарпаны а как такой метод вообще создать.... и передать.
Вроде твой пример (как я понял ты хочешь передать указатель на C# метод, я бы может быть показал более конкретный пример, но двач сожрал звёздочки в твое коде):
https://learn.microsoft.com/en-us/dotnet/api/system.runtime.interopservices.unmanagedcallersonlyattribute?view=net-8.0#examples
самое простое - не привязываться в данном случае к определенному GUI, пусть бэк предоставляет апи, а фронт в любом реактивном фреимворке на выбор, тот же хром запустишь на почти любой ОС.
Marshal.GetFunctionPointerForDelegate()
https://learn.microsoft.com/en-us/dotnet/api/system.runtime.interopservices.marshal.getfunctionpointerfordelegate?view=net-8.0
Должен тоже сработать (+ UnmanagedFunctionPointerAttribute). Плюс это будет проще, так как так можно будет вызвать instance метод,
Комментарии с описание внутренних особенностей/разницы:
https://github.com/dotnet/runtime/issues/65853#issuecomment-1050140999
https://github.com/dotnet/runtime/issues/65853#issuecomment-1050207321
Ты путаешь два типа null - null по ссылке и null по значению.
int? i говорит, что переменная i может иметь значение null, в отличие от int
object? obj говорит, что obj может ссылаться на null, как и любая ссылка
Догадаешься или дальше объяснить?
есть проект, создал два файла: Program.cs и test.cs
в Program.cs определен класс
в test.cs определена функция
почему в Program.cs не видна функция из test.cs?
добавляю пространсва имен: namespace test;
то тут возникает уже ошибка:
Top-level statements must precede namespace and type declarations
может надо эти два файла как-то связать? я думал они автоматически связываются...
читаю по этой проблематике, может быть проблема в Mono?
Спасибо, но я уже пробовал маршал, в итоге просто настроил clangsharp чтобы он intptr без ебли генерил.
![2024-09-0612-42-18.jpg](https://2ch.life/pr/thumb/3218902/17256159567960s.jpg)
Потому что проекты не связаны. В обозревателе решений твоего проекта есть нода "Зависимости". Кликай по ней ПКМ и выбирай "Добавить проект". По умолчанию тебе покажет список проектов твоего решения, но ты так же можешь при помощи кнопки "Обзор" внизу, выбрать проект из стороннего решения.
Единственное правило: зависимости односторонние и не должны замыкаться. Т.е. ты не можешь добавить зависимость с Program.cs на test.cs, потом добавить обратную зависимость с test.cs на Program.cs. Если ты захочешь, грубо говоря, двухсторонний обмен данными между проектами, то сосни хуйца — для этого нужно городить города.
Так же dll-библиотеки добавляются (но лучше юзать nuget).
Ах да, в первый раз тебе захочется выделить проект в списке и нажать ОК, но ничего не произойдет. Слева от названия проекта в списке есть чекбоксы — вот их надо активировать над теми проектами, которые ты хочешь залинковать, и уже потом нажимать ОК.
Если все сделано правильно, то в ноде "Зависимости" появится нода "Проекты" в которой будет список залинкованных проектов (пикрил 2).
да антоша дело в этом. Я только сейчас понял
С# - это чистый ООП язык, в отличие например от С++ (откуда я пришел), который только поддерживает парадигму ООП.
И получается все top-level statements это все находиться внутри функуции main и класса программ.
Бля прихуел я конечно с этого немного.
всем спасибо за помощь
Нихуя. Наллабл референс тайпы исчезают при компиляции оставляя только атрибуты и не меняя поведение кода. Наллабл структуры же просто обёртка в виде Nullable<t>
В моей голове я всегда думал, что если методы запускаются на одном потоке, то у них есть доступ ко всему, что на нём создано, будь то файлы или ещё что. А тут оказывается, что один метод может залочить файл для другого метода на том же потоке. Я правильно пынямаю или нет? Буквально впервые с такой хуйнёй сталкиваюсь за 5 лет
> впервые с такой хуйнёй сталкиваюсь за 5 лет
У меня для вас плохие новости. За 5 лет впервые узнать о существовании дескрипторов странно
И опять-таки, почему тогда другой поток может в него писать, если даже другой метод внутри потока, на котором файл был создан, не может?
Тебе же написали читать про управление ресурсами
Был класс, с какой-то логикой.
Допустим, компьютер. Довольно абстрактный, но достаточный.
Все в нем реализовали. Было заебись.
Вот. Но появилась такая вот хуйня, что нужно по разным причинам иметь теперь телебон(с рассчетом что это смартфон), и ноутбук.
Оба - должны повторять интерфейс компьютера, но при этом - иметь ряд плюшек.
Вроде - ниче сложного же.
Но вот у телебона появляется такая хуйня, что он может быть и не компьютером, а просто дисковым. Вот так вот случилось, хуль поделать, из функций только звонить должен уметь.
Вот.
В общем-то теперь проблема про что.
Если я сделаю с помощью стратегии, и телебон - будет иметь интерфейс компрьютера - мне теперь придется, в интерфейсе звонилки - все равно методы компьютера определить. А мне это не уперлось. А иначе - придется в классе телебона - делать постоянные ветки, дескать - ну, я ж звонилка - извините, о, не звонилка - теперь я это могу.
Не знаю, понятно чи нет. Но вот с такой проблемой столкнулся, и хрен знает как красиво это разрешить.
сегрегация интерфейсов, люк
Либо COP, либо покрывать то-что должно отключаться флагами и при создании объекта подсовывать ему нужный конфиг (что по сути тоже COP, только сбоку)
Мне хочется вот поведения, чтобы с одной стороны - типа наследование(в том плане, что я написал какой-то кусок кода, и он теперь у наследника, без всяких там прокидываний инстанса и передачи вызова уже туда), с другой - интерфейсы, с третий - отсутствие ебатории с тем, что я строю эти ебаные композиции, и пробрасываю куски к тому что реально что-то реализует.
Идеальным для меня было бы что-то типа миксинов+утиной типизации.
В жсах-тсах, это достигается легко. А вот как сделать что-то подобное в шарпах, не извращаясь с рантайм генерацией типов - я не знаю.
хм
///класс
public PC : ICallable, IDiscWriteReadable
//метод
void MakeCall(ICallable callable)
//пример
ICallable pc = new PC()
MakeCall(pc);
в 3 потока выходит 2,5-3кк пакетов в сек (пустые icmp 8) + парсинг каждого. Выглядит что уже упор куда то в ядро лини т.к. банальные увеличение потоков до 4х роняет суммарную производительность к 350-400к пакетов. Утилизация канала за гигабит, если в пакеты пэйлоад добавить то думаю 3-4 гбита точно будет
Пробовал оффлоадинг - без результатов. Все тесты гонял на дебаг билде т.к. в производительность рантайма похоже упора не было