Самый редко используемый цикл в C#
Цикл
Его синтаксис таков:
Этот цикл всегда исполняет своё тело как минимум один раз, даже если условие не выполнено.
Из этой особенности, отличающей
А как часто вы используете
Цикл
do while редко используется, но важно помнить о его существовании, чтобы понимать возможные случаи применения.Его синтаксис таков:
do
{
// тело цикла
} while (condition)Этот цикл всегда исполняет своё тело как минимум один раз, даже если условие не выполнено.
Из этой особенности, отличающей
do while от других видов циклов, вытекают его основные сценарии использования.А как часто вы используете
do while?👍14🤯4😢2🏆2😁1🤬1🌭1
Вопрос от подписчика: "Стоит ли использовать
Здесь важно понимать, чем отличаются эти циклы.
Принцип его работы одинаков везде:
Перебираемому объекту даже не обязательно реализовывать
Разворачивается такой цикл примерно в следующее:
Невооружённым глазом видно, что здесь происходит вызов через VMT, возможен cast, выделение памяти и так далее.
Обслуживание
Так что использование везде
foreach, если for быстрее?"Здесь важно понимать, чем отличаются эти циклы.
▪️for - это классический управляющий оператор, который транслируется в +/- одинаковый IR или машинный код практически во всех языках программирования согласно блок-схеме выше.Принцип его работы одинаков везде:
for (выражение1; выражение2; выражение3)
оператор▪️foreach - это синтаксический сахар над итераторами, который ещё и работает согласно принципам утиной типизации.Перебираемому объекту даже не обязательно реализовывать
IEnumerable.Разворачивается такой цикл примерно в следующее:
var enumerator = enumerable.GetEnumerator();
while (enumerator.MoveNext())
{
var item = enumerator.Current;
// ...
}
Невооружённым глазом видно, что здесь происходит вызов через VMT, возможен cast, выделение памяти и так далее.
Обслуживание
foreach очевидно дороже, потому что это абстракция.Так что использование везде
for вместо foreach - скорее микрооптимизация.🔥11🥴4👍3❤1🥱1
Возможно вы не знали этот метод LINQ
С 6-ой версии в .NET присутствует метод
С 6-ой версии в .NET присутствует метод
Chunk, который позволяет дробить коллекцию на одинаковые кусочки, так называемые "чанки".// получаем итерируемый объектПользуйтесь на здоровье!
var enumerable = Enumerable.Range(1, 999);
// дробим на чанки
var chunks = enumerable.Chunk(29);
// итерируем по чанкам
foreach(var chunk in chunks) // для каждого чанка
{
foreach(var item in chunk) // для каждого элемента в чанке
{
Console.WriteLine(item);
}
}
👍47🤯5🕊3🐳3❤2🥱1
DateTime vs DateTimeOffsetВ .NET есть два главных способа работы со временем:
DateTime и DateTimeOffset.DateTimeOffset это представление абсолютного времени.То есть, речь идёт о моменте во времени, который является однозначно единым для всех.
Другим способом представить мировое время является
DateTime с полем Kind установленным в значение DateTimeKind.Utc.DateTime же представляет другое понятие - календарное время.Календарное время можно представить как точку на чьём-то календаре.
Но мы понимаем, что календарей по всему миру очень много и все они различаются по часовым поясам.
Соответственно,
DateTimeOffset предоставляет тот же функционал, что и DateTime, но вместе со знанием часового пояса.👍12🔥2❤1🤬1
3 причины использовать
Если что-то из этого вам подходит стоит задуматься о смене используемого типа данных 🤔
Необходимо проверить, что из следующего вашему приложению нужно:
1️⃣ Уникально и однозначно определять единый момент во времени.
В системе появится недвусмысленное понятие «сейчас», можно будет логгировать временные метки транзакций, событий, созданий, модификаций и так далее.
2️⃣ Выполнение общих арифметических операций над датой и временем с высокой точностью.
Например, прибавляете к некоторой дате шесть месяцев, и ожидаемый результат должен получиться с поправкой на летнее время.
3️⃣ Хранение нескольких связанных между собой меток времени, как частей одной структуры или одного массива данных.
DateTimeOffset вместо DateTimeЕсли что-то из этого вам подходит стоит задуматься о смене используемого типа данных 🤔
Необходимо проверить, что из следующего вашему приложению нужно:
1️⃣ Уникально и однозначно определять единый момент во времени.
В системе появится недвусмысленное понятие «сейчас», можно будет логгировать временные метки транзакций, событий, созданий, модификаций и так далее.
2️⃣ Выполнение общих арифметических операций над датой и временем с высокой точностью.
Например, прибавляете к некоторой дате шесть месяцев, и ожидаемый результат должен получиться с поправкой на летнее время.
3️⃣ Хранение нескольких связанных между собой меток времени, как частей одной структуры или одного массива данных.
👍12❤1🤬1🥴1
В каких случаях использовать
1️⃣ Работа с датой и временем при отсутствии информации о часовом поясе
2️⃣ Работа только с UTC форматированными датами
3️⃣ При выполнении арифметических операций учитываются только общие результаты
DateTime?1️⃣ Работа с датой и временем при отсутствии информации о часовом поясе
2️⃣ Работа только с UTC форматированными датами
3️⃣ При выполнении арифметических операций учитываются только общие результаты
👍9🥱1
Стоит давать айтишникам выходной в понедельник?
Anonymous Poll
44%
А ну бегом работать! 😡
56%
У меня недостаток смузи в организме 😰
🍌7😁1🕊1🥱1🥴1🐳1🏆1
Внезапная задача
Найдите отличия в приведённых фрагментах кода, и в каком из них находится баг?
1️⃣
2️⃣
Найдите отличия в приведённых фрагментах кода, и в каком из них находится баг?
1️⃣
var children = _childrenRepository.GetByParentIds(parentIds);
return parentIds.ToDictionary(
parentId => parentId,
parentId => children.Where(child => child.ParentId == parentId).ToList());
2️⃣
var children = _childrenRepository.GetByParentIds(parentIds);
var grouped = children.GroupBy(child => child.ParentId);
return grouped
.ToDictionary(
childrenGroup => childrenGroup.Key,
childrenGroup => childrenGroup.ToList());
🤯11🤬2😱1🥱1
StepOne | Степан Минин
Внезапная задача Найдите отличия в приведённых фрагментах кода, и в каком из них находится баг? 1️⃣ var children = _childrenRepository.GetByParentIds(parentIds); return parentIds.ToDictionary( parentId => parentId, parentId => children.Where(child…
Время правильных ответов
Задержался с подведением итогов и написанием правильного ответа.
Сколько живу, столько подтверждаются слова:
«Хочешь что-то спрятать, оставь это у всех на виду».
Действительно, многие подписчики указывали на возможные проблемы с контрактом, равенством, дубликатами, уникальностью и так далее.
Возможно, стоило сразу написать, что все подобные вопросы учтены, и по этим направлениям проблем не предвидится в контексте задачи.
Кто-то боролся за «чистый код», однако лишь под конец дня появился правильный ответ.
А дело в том, что во втором случае теряется информация: в итоговом словаре не будет родительских сущностей с пустой коллекцией дочерних.
Задержался с подведением итогов и написанием правильного ответа.
Сколько живу, столько подтверждаются слова:
«Хочешь что-то спрятать, оставь это у всех на виду».
Действительно, многие подписчики указывали на возможные проблемы с контрактом, равенством, дубликатами, уникальностью и так далее.
Возможно, стоило сразу написать, что все подобные вопросы учтены, и по этим направлениям проблем не предвидится в контексте задачи.
Кто-то боролся за «чистый код», однако лишь под конец дня появился правильный ответ.
А дело в том, что во втором случае теряется информация: в итоговом словаре не будет родительских сущностей с пустой коллекцией дочерних.
❤7👍2🥴2🥱1
Коллеги, поделитесь в комментариях подходами, которые вы используете для рефакторинга.
Интересно, как вы к нему подступаетесь: сразу удаляете старое и встраиваете новое или реализуете своеобразный v2, на который всё постепенно пересаживаете?
Интересно, как вы к нему подступаетесь: сразу удаляете старое и встраиваете новое или реализуете своеобразный v2, на который всё постепенно пересаживаете?
🤔9🥱1🏆1
StepOne | Степан Минин
Коллеги, поделитесь в комментариях подходами, которые вы используете для рефакторинга. Интересно, как вы к нему подступаетесь: сразу удаляете старое и встраиваете новое или реализуете своеобразный v2, на который всё постепенно пересаживаете?
Большое спасибо всем неравнодушным к моей просьбе!
Очень много полезных советов, с инструкцией к применению.
Это точно поможет решить мои проблемы, через некоторое время постараюсь это всё суммировать, чтобы выложить в канал.
Очень много полезных советов, с инструкцией к применению.
Это точно поможет решить мои проблемы, через некоторое время постараюсь это всё суммировать, чтобы выложить в канал.
❤9👍1🥱1
Про ФКН ВШЭ 🎓
Раньше в России можно было стать кандидатом или доктором технических или физико-математических наук.
Присуждение степеней в области компьютерных наук стало возможным благодаря тому, что в 2018 году НИУ ВШЭ получила право присваивать собственные ученые степени.
Как, по-вашему, звучит: "кандидат компьютерных наук"? 🤔
Раньше в России можно было стать кандидатом или доктором технических или физико-математических наук.
Присуждение степеней в области компьютерных наук стало возможным благодаря тому, что в 2018 году НИУ ВШЭ получила право присваивать собственные ученые степени.
Как, по-вашему, звучит: "кандидат компьютерных наук"? 🤔
👍9🤔6
В последнее время часто приходится работать с
Многим известно, что
Но сегодня хочется рассказать о хорошей, как мне кажется, практике проектирования перечисления.
Создавая новое перечисление, старайтесь предоставлять значение по умолчанию.
Иначе
Конечно, так надо делать только в соответствии с описываемой предметной областью.
Такое значение может называться
Такая структура
enum.Многим известно, что
enum это тип значения, определённый набором именованных констант, в каких случаях его удобно использовать и так далее.Но сегодня хочется рассказать о хорошей, как мне кажется, практике проектирования перечисления.
Создавая новое перечисление, старайтесь предоставлять значение по умолчанию.
Иначе
default(TEnum) может вернуть первое значение из перечисления, что может приводить к логическим несостыковкам и смысловым ошибкам.Конечно, так надо делать только в соответствии с описываемой предметной областью.
Такое значение может называться
None, Default или Unknown.Такая структура
enum позволит описать, как работать с вашим пользовательским типом данных.👍17🔥1
Продолжаю экспериментировать с DI
Допустим, у нас есть некий сервис
Внезапно возникла потребность "задекорировать" его некоторым
Ну всякое бывает, правда ведь?)
Когда под рукой только стандартный DI контейнер .NET, то на ум приходит следующее:
Естественно, это не заработает, программа зависнет на веки вечные.
Однако, проблема решаема с помощью библиотеки Scrutor.
Она добавляет методы расширения для
Допустим, у нас есть некий сервис
IFooService:interface IFooService
{
void DoStuff();
}
Внезапно возникла потребность "задекорировать" его некоторым
FooDecorator.Ну всякое бывает, правда ведь?)
Когда под рукой только стандартный DI контейнер .NET, то на ум приходит следующее:
// регистрируем основную реализацию
services.AddSingleton<IFooService, FooService>();
// пытаемся задекорировать
services.AddSingleton<IFooService>(sp =>
{
var fooService = sp.GetRequiredService<IFooService>();
return new FooDecorator(fooService);
});
Естественно, это не заработает, программа зависнет на веки вечные.
Однако, проблема решаема с помощью библиотеки Scrutor.
Она добавляет методы расширения для
IServiceCollection, которые позволяют эффективно пользоваться всеми преимуществами паттерна "Декоратор":services.Decorate<IFooService, FooDecorator>();
🔥11👍2🤩1🥴1
Как лучше регистрировать коллекцию зависимостей?
Представим, что вам нужно внедрить коллекцию из сервисов типа
Что приходит на ум?
▪️Создать свою кастомную коллекцию, и зарегистрировать её.
▪️Буквально зарегистрировать объект списка или массива с набором нужных зависимостей
Однако можно поступить гораздо проще и просто регистрировать зависимости как обычно. Например:
DI контейнер всё поймёт и даже если будет зарегистрирована всего одна реализация, она будет представлена в коллекции.
Представим, что вам нужно внедрить коллекцию из сервисов типа
IMyService. Тогда вы ожидаете её вот так:class MyOtherService : IMyOtherService
{
public MyOtherService(IEnumerable<IMyService> myServices)
{
//...
}
}
Что приходит на ум?
▪️Создать свою кастомную коллекцию, и зарегистрировать её.
▪️Буквально зарегистрировать объект списка или массива с набором нужных зависимостей
Однако можно поступить гораздо проще и просто регистрировать зависимости как обычно. Например:
services.AddScoped<IMyService, MyService>();
DI контейнер всё поймёт и даже если будет зарегистрирована всего одна реализация, она будет представлена в коллекции.
🤯8👍6❤1🔥1
Шёл 2023-й год, а некоторые C# разработчики, даже "ведущие", продолжают штамповать обобщённые репозитории...
Мда...🤡
https://habr.com/ru/companies/itq_group/articles/747566/
Мда...🤡
https://habr.com/ru/companies/itq_group/articles/747566/
Хабр
C# Generic-подход к разработке web API
Мини-туториал от ведущего разработчика "ITQ Group" Александра Берегового. В этой статье рассмотрим применение обобщенного подхода при разработке WEB API. В моей практике несколько раз приходилось...
🥴8😁3👍1😱1🤩1
StepOne | Степан Минин
Шёл 2023-й год, а некоторые C# разработчики, даже "ведущие", продолжают штамповать обобщённые репозитории... Мда...🤡 https://habr.com/ru/companies/itq_group/articles/747566/
Об этом не писал только ленивый…
Итак, почему обобщённый репозиторий - это антипаттерн.
Прежде всего, давайте вспомним, что из себя представляет паттерн репозиторий, особенно популярный в DDD.
Согласно Дяде Бобу, репозиторий посредничает между доменом и слоем представления данных, находясь в роли in-memory коллекции доменных объектов.
Проще говоря, это фасад для доступа к данным, который оборачивает конкретный источник данных: ORM, сервис, СУБД, файловая система, Active Directory и т.д.
Так вот, начну с неочевидного.
Если вы используете ORM, например, Entity Framework или NHibernate, то следует помнить, что эти библиотеки сами по себе предоставляют реализации не только обобщённых репозиториев, но и единиц работы Unit Of Work.
В случае EF
В случае NHibernate оба паттерна инкапсулированы внутри
Соответственно, создание новой обёртки поверх существующей аналогично переизобретению колеса, которое ещё и будет квадратным.
В отрыве от ORM, конечно обобщённые репозитории, в силу своей "обобщённости", превращаются в DAL код, намертво впаенный в алгоритмы бизнес-логики.
В результате, когда запросы будут устаревать, окажется, что по всему проекту разбросана неактуальная и сложная логика запросов, которую трудно поддерживать.
Также, репозиторий - это абстракция, которая больше нужна для работы с доменом, нежели с данными, и, соответственно, является его частью.
А домен не является обобщённым. Не каждая сущность может быть добавлена/удалена или отредактирована единым образом, не у каждой сущности будет репозиторий вовсе.
Запросы кардинальным образом различаются, вследствие этого API конкретного репозитория становится уникальным, согласно соответствующей сущности.
С другой стороны, репозиторий определяет операции, которые хранилище данных можнт осуществлять над доменными объектами.
А обобщённый вариант не предоставляет осмысленного контракта.
Просто сравните две сигнатуры ниже:
Все эти аргументы говорят в пользу того, что создание обобщённых репозиториев - плохо в любом году.
Итак, почему обобщённый репозиторий - это антипаттерн.
Прежде всего, давайте вспомним, что из себя представляет паттерн репозиторий, особенно популярный в DDD.
Согласно Дяде Бобу, репозиторий посредничает между доменом и слоем представления данных, находясь в роли in-memory коллекции доменных объектов.
Проще говоря, это фасад для доступа к данным, который оборачивает конкретный источник данных: ORM, сервис, СУБД, файловая система, Active Directory и т.д.
Так вот, начну с неочевидного.
Если вы используете ORM, например, Entity Framework или NHibernate, то следует помнить, что эти библиотеки сами по себе предоставляют реализации не только обобщённых репозиториев, но и единиц работы Unit Of Work.
В случае EF
DbContext является UOW, а DbSet<T> это обобщённый репозиторий.В случае NHibernate оба паттерна инкапсулированы внутри
ISession.Соответственно, создание новой обёртки поверх существующей аналогично переизобретению колеса, которое ещё и будет квадратным.
В отрыве от ORM, конечно обобщённые репозитории, в силу своей "обобщённости", превращаются в DAL код, намертво впаенный в алгоритмы бизнес-логики.
В результате, когда запросы будут устаревать, окажется, что по всему проекту разбросана неактуальная и сложная логика запросов, которую трудно поддерживать.
Также, репозиторий - это абстракция, которая больше нужна для работы с доменом, нежели с данными, и, соответственно, является его частью.
А домен не является обобщённым. Не каждая сущность может быть добавлена/удалена или отредактирована единым образом, не у каждой сущности будет репозиторий вовсе.
Запросы кардинальным образом различаются, вследствие этого API конкретного репозитория становится уникальным, согласно соответствующей сущности.
С другой стороны, репозиторий определяет операции, которые хранилище данных можнт осуществлять над доменными объектами.
А обобщённый вариант не предоставляет осмысленного контракта.
Просто сравните две сигнатуры ниже:
// вообще не понятно, что происходит
T Find(object param);
// более читабельный код, который чётко определяет
// отношение между хранилищем данных и доменным объектом
Customer FindCustomerByName(string name);
Все эти аргументы говорят в пользу того, что создание обобщённых репозиториев - плохо в любом году.
👍17❤2🥱2🔥1
- «Нами вообще никто не руководил. Однажды мне абсолютно нечего было делать, и я ушёл заниматься сёрфингом, потому что работал удалённо. Мне никому не нужно было отчитываться. Казалось, никто даже не знал, что я работаю у них», — так рассказывает бывший сотрудник Meta*, проработавший в компании два месяца. Его приняли в команду на должность дата-саентиста начального уровня.
Ну что ребят, я пошёл изучать data science 😁
https://habr.com/ru/companies/ruvds/articles/749056/
Ну что ребят, я пошёл изучать data science 😁
https://habr.com/ru/companies/ruvds/articles/749056/
Хабр
Причины «имитации работы» в Big Tech
Когда Грэма приняли в Amazon, ему казалось, что это работа его мечты. Его привлекли как учёного-исследователя в помощь для разработки функций голосового помощника Alexa. Грэм (имя изменено)...
🤯7🤣4😁1😱1