.NET Разработчик
6.51K subscribers
427 photos
2 videos
14 files
2.04K links
Дневник сертифицированного .NET разработчика.

Для связи: @SBenzenko

Поддержать канал:
- https://boosty.to/netdeveloperdiary
- https://patreon.com/user?u=52551826
- https://pay.cloudtips.ru/p/70df3b3b
Download Telegram
День 1459. #Карьера
Улучшаем Эмоциональный Интеллект. Часть 6
Эмоциональный интеллект – это способность понимать эмоции и управлять ими, бесценное качество, которое поможет стать более продуктивными и улучшить отношения с другими. Вот простые правила, которые помогут развить ваш эмоциональный интеллект.

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

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

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

Исследовательская фирма Gallup обнаружила, что сотрудники, менеджеры которых проводили с ними регулярные встречи, были почти в три раза более заинтересованы в работе, чем их коллеги, у которых регулярных встреч не было. Сотрудники, которые ежедневно общались со своими менеджерами, были наиболее вовлечены. Извините, но придётся терпеть митинги.
Отвечать на письма — это одно; проявление личного интереса - другое. Исследование также показало, что сотрудники ценят общение не только в отношении своих ролей и обязанностей, но и о жизни вне работы.

А как же наша личная жизнь?
В исследовании, проведенном психологами из Цюрихского университета, участникам было предложено встретиться с тремя людьми, которые им небезразличны, в течение недели, чтобы «подарить им своё время» (в смысле, больше, чем они обычно с ними проводили). По сравнению с другой группой, которая писала о своих воспоминаниях в ежедневном журнале, «дарившие время» сообщали о большем уровне счастья. Чем дольше они продолжали практику, тем более счастливыми себя чувствовали.

Вы можете сделать то же самое.
Почему бы не подарить кому-нибудь своё время? Выберите человека, которому вы хотели бы уделить часть своего времени, а затем запланируйте сделать с ним что-то, чего вы обычно не делаете:
- пригласите в гости или на ужин или даже просто на кофе;
- прогуляйтесь в парке;
- позвоните по видео-связи старому другу, которого вы не видели целую вечность;
- возьмите отгул после обеда, чтобы провести время с другом, ребёнком или другим членом семьи.

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

Но учтите также и следующее: вы почти не помните время, проведённое в одиночестве, но вы помните время, проведённое с другими. Таким образом, просто делясь своим временем с другими, вы делаете инвестиции: вы создаёте воспоминания на будущее.

Поэтому, планируя предстоящую неделю, помните:
Время — самый ценный ресурс, который у вас есть. Тратьте его с умом. Потому что, как только оно уйдет, вы никогда не вернёте его обратно.

Источник: https://www.inc.com/justin-bariso/how-to-increase-emotional-intelligence.html
👍12
День 1460. #ЗаметкиНаПолях
Ref-поля в C#11
Ключевое слово ref указывает, что переменная передаётся по ссылке. Это позволяет вызываемой функции изменить значение переменной в вызывающем её коде. C# поддерживает ref для аргумента метода или возврата метода, а также для локальной переменной:
int i = 10;

Foo(ref i);

ref int Foo(ref int j)
{
ref int k = ref i;
return ref j;
}

В этом примере параметр j и локальная переменная k являются псевдонимами для переменной i. Когда вы получаете их значения, читается i, а когда устанавливаете - устанавливается значение i. Ref-переменные могут указывать как на память на стеке, что подразумевает строгие правила области видимости, так и на память в куче, которой управляет сборщик мусора.

Компилятор сохраняет область видимости, т.е. разрешено возвращать ref j, потому что компилятор знает, что переменная, на которую ссылается параметр, всё ещё будет в области видимости. Компилятор не позволит вам вернуть ссылку на k, потому что локальная ссылка может указывать на стековую память, которая выйдет за пределы области видимости при возврате из метода.

C#8 представил ref-структуры и использовал их для реализации Span. Тип Span — это абстракция в стеке для области памяти стека или кучи. Для представления памяти Span нужны два поля: ref-поле, указывающее на первый элемент памяти, и поле для хранения длины блока памяти. До C#11 ref-поле было внутренней реализацией среды выполнения.

В C#11 ref-поля открыты для общего использования. Они позволяют вам определить ваши собственные ref-структуры имеющие ref-поля. Например, вы можете создать тип, читающий информацию из большой структуры, которая может находиться в стеке, в куче или даже в неуправляемой памяти:
struct MyStruct { 
/* большая структура */
}

ref struct StructReader
{
ref MyStruct _value;
public StructReader(ref MyStruct value)
=> _value = ref value;

public void ReadValue(Span<byte> value)
{ … }

}

При передаче ссылок в методы ref-структуры компилятор гарантирует, что переменные, на которые вы ссылаетесь, не выйдут за пределы области видимости раньше, чем сама структура. В противном случае ref-структура могла бы ссылаться на переменные вне области видимости:
void Process(ref StructReader reader)
{
Span<byte> buffer = stackalloc byte[10];

reader.ReadSomeValue(buffer);
}

Здесь будет выдана ошибка CS8352: Cannot use variable 'buffer' in this context because it may expose referenced variables outside of their declaration scope (Невозможно использовать переменную 'buffer' в этом контексте, потому что она может раскрыть переменные, на которые она ссылается, за пределы области их объявления).

Вы можете указать компилятору разрешить передачу этих переменных, добавив ключевое слово scoped. Тогда компилятор запретит сохранять такие параметры в структуре:
public void ReadSomeValue(
scoped Span<byte> value
)
{ … }

Т.е. ключевое слово scoped указывает компилятору обращаться с аргументом value так же, как если бы он был локальной переменной в методе.

Источник: https://developers.redhat.com/articles/2023/01/11/5-new-advanced-features-improving-c-11#ref_fields
👍4
День 1461. #МоиИнструменты
Полезные NuGet-Пакеты для Юнит-Тестирования
Помимо всем известных пакетов для юнит-тестирования, вроде Moq, NSubstitute или FluentAssertions, есть менее популярные, но оттого не менее полезные. Ниже приведу некоторые из них.

1. JustMock Lite
Это бесплатный пакет с открытым исходным кодом, который упрощает юнит-тестирование, простой в использовании, многофункциональный, мощный и гибкий. Он похож на Moq, но, как мне показалось, имеет более понятный fluent-API настройки и более богатую функциональность. JustMock Lite — бесплатная версия коммерческого продукта JustMock.

2. System.IO.Abstractions
В основе библиотеки лежат IFileSystem и FileSystem. Вместо прямого вызова таких методов, как File.ReadAllText, используйте IFileSystem.File.ReadAllText. Они имеют точно такой же API, который можно внедрять и тестировать. Библиотека также поставляется с набором тестовых помощников, чтобы избавить вас от необходимости имитировать каждый вызов для базовых сценариев. Они не являются полной копией реальной файловой системы, но помогут вам в тестах.

3. DeepEqual
Это расширяемая библиотека для глубокого сравнения. Чтобы проверить экземпляры объектов на равенство, просто вызовите метод расширения IsDeepEqual:
bool result = obj1.IsDeepEqual(obj2);
При использовании внутри теста вы можете вместо этого вызвать ShouldDeepEqual. Этот метод выдает исключение с подробным описанием различий между двумя объектами:
obj1.ShouldDeepEqual(obj2);
Также библиотека имеет fluent-API для кастомизации сравнения (например, можно игнорировать отдельные свойства).

4. ObjectDumper.Net
Это утилита, предназначенная для сериализации объектов C# в строку для целей отладки и ведения журнала. Вы можете использовать её в любом проекте .NET, совместимом с PCL. ObjectDumper предоставляет два отличных способа визуализации объектов .NET в памяти:
- DumpStyle.Console: сериализует объекты в удобочитаемые строки, часто используется для записи сложных объектов C# в файлы журналов.
- DumpStyle.CSharp: сериализует объекты в код инициализатора C#, который можно использовать для повторного создания объекта C#.

5. MockHttp
Это тестовый слой для библиотеки Microsoft HttpClient. Он позволяет настраивать заглушки для HTTP-ответов и может использоваться для тестирования сервисного уровня приложения.
MockHttp определяет замену HttpMessageHandler, механизма, управляющего HttpClient, который предоставляет гибкий API конфигурации и предоставляет готовый ответ. Вызывающий объект (например, сервисный уровень вашего приложения) остается в неведении о его наличии.

Источник: https://blog.markoliver.website/Testing-In-Dotnet
👍20👎1
День 1462. #Здоровье
Слишком Много Сидеть Вредно, но Снизить Вред Легко
Конечно, вы слышали об опасностях сидения весь день, но что поделать, такая работа, верно? Нет. Согласно исследованию, опубликованному в Американского колледжа спортивной медицины, пять минут легкой ходьбы каждые полчаса могут помочь снизить риск, связанный с длительным сидением в течение дня.

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

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

Пять минут каждые полчаса вам всё ещё сложно выделить? Было показано, что даже небольшие «активные перерывы», даже минута ходьбы каждый час, снижали артериальное давление у участников исследования. Все участники исследования, как правило, были здоровыми взрослыми, а это означает, что люди с хроническими заболеваниями могут увидеть ещё большую пользу.

Регулярные «активности» могут казаться недостижимыми, если офисная культура не способствует этому. Существуют социальные нормы, согласно которым, если вы встаете из-за стола, люди думают, что вы не работаете.

Авторы исследования работали над тем, чтобы убедить работодателей в важности движения в течение рабочего дня — не только для личного здоровья, но и для повышения продуктивности. Упражнения в течение 150 минут в неделю могут снизить кровяное давление и уровень холестерина у некоторых взрослых. Повышение уровня активности — первый шаг к этому. Сидение — это профессиональный риск, а здоровый работник — более продуктивный работник. Команда обнаружила, что участники, прерывавшие сидение, принесли больше, чем просто пользу для собственного физического здоровья. Это также снижало их усталость и улучшало настроение.

Просто сидеть за столом и работать в течение 8 часов на самом деле может быть не так уж и здорово, если вы беспокоитесь об общей производительности своей работы. И хотя стоячие столы набирают популярность, они не всегда применимы. Также нет веских научных доказательств того, что стоять действительно лучше, чем сидеть. У людей может возникнуть ложное ощущение, что они здоровы, потому что они используют стоячий стол, хотя, возможно, на самом деле им не лучше.

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

Вы можете просто поприседать, мягко вставая и снова садясь. Если у вас много места, можно делать танцевальную паузу под любимую песню (большинство песен как раз длятся 3-5 минут). Если места мало, можно потягиваться или двигать руками во всех направлениях, выполнять боковые наклоны и скручивания на стуле. Даже когда вы не можете пошевелить нижней частью тела и на самом деле встать с сидения, активное глубокое дыхание, задействующее диафрагму и двигающее ребра, полезно для вашей осанки и общего состояния здоровья. Общая идея состоит в том, чтобы двигаться всеми возможными способами в зависимости от ваших возможностей.
Любой активный перерыв в сидении всё равно принесёт некоторую пользу.

Источник: https://edition.cnn.com/2023/01/12/health/sitting-prolonged-study-wellness/index.html
👍25
День 1463. #ЗаметкиНаПолях
Разбираем Ключевое Слово Unchecked в C#
Ключевое слово unchecked в C# используется для отключения проверки переполнения для целочисленных операций в блоке кода. Т.е. программа не выбросит исключение и продолжит работу с результирующим значением, если операция может вызвать переполнение или потерю значимости. Это поведение по умолчанию для целочисленных операций в C#:
int x = int.MaxValue; 
x = x + 1;
Здесь x будет равно -2147483648, исключения не будет.

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

Чтобы такого не происходило, в C# есть ключевое слово checked, которое может быть использовано, чтобы указать, что операция или блок кода должен выбрасывать исключение при переполнении:
int x = int.MaxValue; 
checked
{
x = x + 1;
}
Этот код выбросит System.OverflowException.

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

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

Рассмотрим несколько примеров:
Console.WriteLine(
unchecked(long.MaxValue + long.MaxValue)
);
Console.WriteLine(
unchecked((ulong)(long.MaxValue + long.MaxValue))
);
Console.WriteLine(ulong.MaxValue);

В коде выше long.MaxValue + long.MaxValue превышает максимальное значение, которое может представлять long, но из-за ключевого слова unchecked программа не выдаст исключения. Вместо этого переполнение выдаст результат, в данном случае -2.
Во втором случае результат будет преобразован в ulong, т.е. 18446744073709551614.
В третьем случае мы просто выводим максимальное значение для ulong -
18446744073709551615.

Итого
Когда арифметическая операция возвращает число, которое слишком велико или слишком мало для представления используемым типом данных, такое состояние называется переполнением (overflow).
Подобно переполнению, недополнение (underflow) происходит, когда результат операции слишком мал, чтобы быть представленным типом данных.

В языке C# есть техника, называемая переносом (wrap-around), для управления переполнением и недополнением в обеих ситуациях. Т.е. в случае переполнения, всё, что выше максимального значения, будет добавлено к минимальному значению типа, например:
int.MaxValue + 1 = int.MinValue;
аналогично для недополнения:
int.MinValue – 2 = int.MaxValue - 1;

Заметьте, что несмотря на то, что арифметические операции над переменными по умолчанию исполняются в unchecked контексте, константные выражения вычисляются по умолчанию в проверяемом (checked) контексте, а в случае переполнения возникает ошибка времени компиляции. Т.е. нельзя использовать
x = int.MaxValue + 1;
При использовании констант нужно явно указать unchecked контекст:
x = unchecked(int.MaxValue + 1);

Источник: https://dev.to/simsekahmett/understanding-and-using-the-unchecked-keyword-in-c-hfg
👍10
День 1464. #Курсы
Функциональный Февраль
Когда я только начинал вести этот канал (а недавно ему исполнилось 4 года), в одном из первых постов я упомянул ресурс для прохождения упражнений на программирование Exercism. Он не такой популярный, как Codewars или LeetCode, но я тогда о них не знал, а этот попался первым.

В общем, сейчас не собственно о сайте, а о челлендже, который они запустили в этом году #12in23. Суть в том, что вы изучаете 12 разных языков в течение 2023 года, а Exercism помогает вам в этом, выпуская интересные видео с рассказами о каждом из языков, а также упражнения на этих языках. Январь мы, очевидно, пропустили, но можно начать с февраля, тем более что на февраль запланирован челлендж по функциональным языкам.

И первое видео из этой серии – об F#. Если честно, я давно хотел его попробовать, но всё не доходили руки, да и не было мотивации. И вот подвернулся случай. Итак, видео с объяснением основных концепций функционального программирования вообще и F# в частности тут - https://youtu.be/uIFGx1SDnWI

А сам челлендж #12in23здесь. Сайт требует регистрации, но можно зайти через аккаунт на GitHub. Изучайте язык по видео, выполните 5 заданий на любом из функциональных языков до конка февраля и получите бейдж «Functional February».
👍19
День 1465. #CodeReview
Как Оптимизировать Обзоры Кода
Обзоры кода требуют значительных временных затрат, и важно понять, как инженеры могут извлечь из них максимальную пользу. Процесс проверки кода (с помощью некоторой автоматизации) может быть идеальной возможностью для членов команд развить навыки асинхронного общения и внести вклад в обмен знаниями в команде.

Доверьтесь асинхронной связи
Пандемия положила начало периоду самоизоляции, и многие из нас теперь работают из дома. Благодаря этому эффективная асинхронная связь стала первостепенной задачей. В дополнение к email и мессенджерам, проверка пулл-реквестов является вариантом асинхронного общения. У асинхронного общения есть свои преимущества:
- Люди из разных часовых поясов могут чувствовать себя вовлеченными.
- Удобно для людей с разным знанием языка (человеческого, а не языка программирования).
- Обеспечивает гибкость для людей с разными графиками.

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

А стандарты код-ревью помогут уменьшить трения, связанные с двусмысленностью. Например, разъяснение того, какой отзыв является придиркой, а какой отзыв фактически блокирует слияние, помогает прояснить ожидания для всех, кто участвует в процессе проверки. Этих проблем можно избежать, выделив время всей командой для определения стандартов.

Ещё есть документация. Очень сложно подготовить хорошую документацию для проектов, особенно если нет специального технического писателя. Обратите внимание на пассивную документацию: способы обмена информацией без активного участия, т.е. все виды артефактов, которые команды создают, когда они исследуют, проектируют и создают продукт публично. Пассивная документация включает письменный диалог для исследования ошибки или описания пулл-реквестов. Да, «пассивные документы» сложнее искать, если у них нет специального оглавления или маркировки, но они обеспечивают удобный формат для обмена знаниями.

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

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

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

3. Автоматизация должна расширять возможности людей. Эффективная автоматизация должна позволять людям полностью владеть определёнными функциями. Например, автоматическое перемещение пулл-реквеста в ишью, при получении отзыва, пометка его и назначение его исполнителю даст команде больше понимания того, кто владеет какими функциональными областями. Вместо того, чтобы отправлять задачу в общую кучу невыполненной работы, автоматизация поможет поддерживать действенность обратной связи.

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

Источник: https://github.com/readme/guides/code-review-optimization
👍7
День 1466. #юмор
👍18
День 1467. #Карьера
Улучшаем Эмоциональный Интеллект. Часть 7
Эмоциональный интеллект – это способность понимать эмоции и управлять ими, бесценное качество, которое поможет стать более продуктивными и улучшить отношения с другими. Вот простые правила, которые помогут развить ваш эмоциональный интеллект.

7. Защитное одеяло
«Я страдаю от синдрома самозванца. Я беспокоюсь, когда пишу отзывы и конструктивную критику своим сотрудникам».

Знакомо? Вы не одиноки. Но есть эмоционально-интеллектуальный трюк, который вы можете использовать, чтобы избавиться от этих чувств, обрести уверенность в себе и быть на высоте. Мне нравится называть это защитным одеялом.

Маленькие дети часто бывают очень стеснительны, особенно когда попадают в незнакомую компанию. Им трудно заговорить или играть с незнакомыми, особенно взрослыми. Они стараются спрятаться за родителей, в укромном месте или даже за своими руками. Но постепенно они набираются смелости и раскрепощаются. При этом присутствие родителей или нахождение в знакомой обстановке помогает им в этом. Это что-то вроде защитного одеяла. Без него они бессильны, а с ним могут победить свои страхи и быть самими собой.

Ты (и я) такие же. Нам нужно чувствовать себя в безопасности, прежде чем мы сможем быть самим собой и полностью раскрыть свой потенциал.

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

В команде с высокой психологической безопасностью товарищи чувствуют себя в безопасности, рискуют рядом с членами своей команды. Они уверены, что никто в команде не будет смеяться над ними, осуждать или наказывать за признание ошибки, задавание вопроса или предложение новой идеи. Другими словами, в психологически безопасной среде вы можете высказывать своё мнение и даже шутить, не беспокоясь о том, что другие сочтут вас странным или глупым.

Проблема, однако, в том, что вас часто загоняют в среду, где вы совсем не чувствуете себя в безопасности. На работе (а иногда и дома) вы чувствуете на себе осуждение за высказывание своих мыслей. И вы вынуждены, образно говоря, «спрятаться за руками».

Вам нужно защитное одеяло. Что может им быть?

- Человек (или люди): наставник, друг, доверенное лицо или даже группа друзей — любой, кто хорошо знает вас и на что вы способны, и кто может напомнить вам об этом.

- Уединение: если вы интроверт, некоторое время в одиночестве может зарядить вас физически, умственно и эмоционально.
- Что-то ещё, что успокаивает лично вас.

- «Голубой дельфин»: позитивная мысль, которую вы можете использовать, чтобы заменить негативные мысли. Например, если перед важной встречей вам забивает голову мысль «главное не нервничать», и от неё вы начинаете нервничать ещё больше, говорите себе: «Я так взволнован. Все должно пройти отлично». Используете потенциальный негатив — свою нервозность — и трансформируете его в позитив. Вы не сможете предотвратить появление негативных мыслей. Но ваш голубой дельфин позаботится о том, чтобы они не задерживались надолго. Это поможет вам заставить мысли и эмоции работать на вас, а не против вас.

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

Источник: https://www.inc.com/justin-bariso/emotional-intelligence-self-confidence-how-to-be-your-best-self.html
👍9
День 1468. #ВредныеСоветы
11 Способов Усложнить Себе Жизнь в C#. Начало
Программировать тяжело. Большинство из нас работает в командах, создавая ПО, с которым будут работать другие люди. Поэтому важно, чтобы мы старались облегчить жизнь нашей команды. Вот 11 примеров, как НЕ надо делать в C#.

1. Злоупотребление циклами
Цикл for существует во многих языках. Вы видели его миллион раз:
for(int i = 0; i < 10; i++) { }

Делать так нормально, но некоторые слишком творчески подходят к написанию циклов. Для начала рассмотрим структуру цикла for:
for (выражение «до»;
условие;
выражение «после» каждой итерации)
{}
3 выражения в круглых скобках задают условия выполнения цикла. Но это просто операторы, как и любые другие. А значит вы можете написать там всё, что захотите.

Начнём с создания бесконечного цикла, оставив каждое из трех выражений пустым:
// вместо:
while (true) {}
// можно написать:
for (; ;) {}
Хотя это не слишком полезно.

Можно опустить третье выражение и добавить приращение в условное выражение:
for(int i = 0; ++i < 100;) {}

Можно использовать строки. Удалим буквы из строки по одной:
for (string name = "Brendan"; 
name.Length > 0;
name = name.Substring(1))
{
Console.WriteLine(name);
}

Чтобы совсем оторваться, создадим несколько переменных и будем использовать их в цикле! Можно использовать кортежи:
for (
var (number, name) = (1, "Brendan");
number < 7;
name += number.ToString(), number += 1)
{
Console.WriteLine(name);
}

2. Построение и деконструкция кортежа в конструкторе
Кстати, о кортежах. Вы можете конструировать и деконструировать кортежи в одной и той же строке. Удивим команду, поместив весь конструктор в одну строку:
public Person(string prefix, string first, string middle, string last, string suffix, string nickname, DateTime birthday, string favoriteColor)
{
(Prefix, First, Middle, Last, Suffix, Nickname, Birthday, FavoriteColor) = (prefix, first, middle, last, nickname, suffix, birthday, favoriteColor);
}

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

Заметили? Тут есть ошибка.
Да, nickname и suffix перепутаны местами. И тут не будет ошибки компилятора, так как они одного типа.

Продолжение следует…

Источник:
https://brendoneus.com/post/Ways-Of-Making-CSharp-Harder/
👍13
День 1469. #ВредныеСоветы
11 Способов Усложнить Себе Жизнь в C#. Продолжение
Начало

3. Чрезмерное или недостаточное использование var
Var, на самом деле, замечательное дополнение к языку, позволяющее не указывать тип переменной, поскольку компилятор уже знает этот тип. Но просто нигде не указывать тип, а использовать var, - это перебор. Var полезен, когда тип сложный:
// ясно, но длинно
IEnumerable<IGrouping<DateOnly, Person>> peopleGroupedByBirthdate =
people.GroupBy(
p => p.Birthdate,
p => p);

// менее ясно, но короче
var peopleGroupedByBirthdate =
people.GroupBy(
p => p.Birthdate,
p => p);

Именно для таких сложных типов (и анонимных типов) необходим var. На самом деле почти везде, где результат GroupBy хранится в переменной, вы, скорее всего, увидите в коде var. Иногда это связано с тем, что результат должен быть преобразован в новый анонимный тип.

Тогда почему бы просто не использовать его везде? Потому, что var скрывает информацию:
var author1 = GetAuthor1();
var author2 = GetAuthor2();
var authorName = GetAuthorName();
var authorFullName = GetAuthorFullName();

Мы не можем определить тип этих переменных, не наведя на них курсор. Скорее всего, GetAuthorName и GetAuthorFullName одного типа, но вовсе не факт. Мне знакомы люди, которые бросались из крайности в крайность: от полного неприятия var до использования его повсеместно. Как везде, важен баланс. Если вы заметили, что наводите курсор на переменную, чтобы узнать её тип, задумайтесь, может стоит указать его явно?

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

Иногда может быть необходимо не исправлять одно-два предупреждения, поэтому есть параметр NoWarn, который можно установить в проекте, чтобы указать предупреждения, которые следует игнорировать. Если вы действительно хотите развлечь команду, просто добавляйте по одному предупреждению для игнорирования каждый раз, когда с ним сталкиваетесь. Тогда ваш код будет без предупреждений!
<NoWarn>12345,23456,34567,45678,56789</NoWarn>

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

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

Продолжение следует…

Источник:
https://brendoneus.com/post/Ways-Of-Making-CSharp-Harder/
👍13
День 1470. #ВредныеСоветы
11 Способов Усложнить Себе Жизнь в C#. Продолжение
1-2
3-4

5. Работа с disposable-типами без using
Говоря о disposable-типах, мы обычно имеем в виду, что тип реализует интерфейс IDisposable. Когда вы создаёте экземпляр такого типа, он должен очищаться после использования. В помощь вам выражение using:
using (var sw = new StreamWriter(path, true))
{
sw.WriteLine("Test");
}

Если вы хотите расстроить команду, перестаньте использовать using. Что может пойти не так? Многое. Тип реализует IDisposable, чтобы его можно было правильно очистить, т.е. освободить ресурсы (сетевые подключения, дескрипторы файлов и т.д.), которые использовал тип, перед его удалением. Если их правильно не освободить, они останутся открытыми:
SqlConnection conn = new (connString)
SqlCommand command = new (query, conn);
connection.Open();
SqlDataReader reader = command.ExecuteReader();
while (reader.Read())
{

}

Здесь объекты SqlConnection и SqlDataReader необходимо очищать. Если вы волнуетесь за вложенность, начиная с C#8 можно использовать декларации using, т.е. не заключать код в фигурные скобки.
using SqlConnection conn = new (connString);

using SqlDataReader reader = command.ExecuteReader();

Здесь переменные conn и reader будут освобождены в конце текущего блока кода (например, при выходе из метода).

См. также «Мои любимые ошибки с IDisposable»

6. Генерация исключений вместо возврата
Вы можете привлечь внимание обзорщика (меня точно) к вашему коду, если в ожидаемой или вероятной ситуации выбросите исключение вместо того, чтобы просто обработать этот вариант и вернуть значение.
Пользователь забыл ввести значение? Это ошибка валидации, а не исключительный случай. Мы можем (и должны) возвращать результат ошибки валидации, чтобы проинформировать пользователя о проблеме. Если же значение отсутствовало во внутренних расчетах, это проблема целостности данных после валидации - исключительный случай, который может потребовать остановки кода, чтобы предотвратить дальнейшие проблемы.

Как удивить команду? Ну, в теории можно построить всю логику приложения на исключениях:
private void UpdateProfile(Profile data)
{
if (data is null)
throw new ArgumentNullException(nameof(data));
if (string.IsNullOrWhiteSpace(data.FullName))
throw new ArgumentException("Missing Name", nameof(data));

// сохраняем изменения

throw new UpdatedSuccessfullyException(data);
}

Это примерно как события, если не обработать которые, приложение упадёт.

Продолжение следует…

Источник:
https://brendoneus.com/post/Ways-Of-Making-CSharp-Harder/
👍8
День 1471. #ВредныеСоветы
11 Способов Усложнить Себе Жизнь в C#. Продолжение
1-2
3-4
5-6

7. Использование непонятных сокращений для имён переменных
Очень важно, чтобы читатель кода знал, для чего переменная предназначена. Если вы хотите усложнить кодовую базу, вы можете добавить в имена сокращения и аббревиатуры.

Даже если аббревиатура распространена в вашей кодовой базе или домене, может возникнуть путаница, о которой вы даже не подумали. Когда у вас есть куча этих внутренних обязательных знаний в предметной области, это значительно усложняет приглашение в вашу команду новых людей, поскольку им придётся выучить этот список сокращений:
var st = new SimpleTransfer();
var st = new ServiceTime();
var st = new SecretTunnel();

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

Вот некоторые аббревиатуры, которые мне встречались в коде, и являлись не тем, чем казалось на первый взгляд:
"E2E" – не End-to-End,
"IRS" – не имело отношения к налогам,
"IBM" – не про компьютерную компанию,
"S3" – не про хранилище AWS,
"DDL" – не DataDefinitionLanguage и не DropDownList,
"DLL" – не DynamicLinkLibrary.

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

1) Классическая i в стандартном цикле for. Если вы не используете саму переменную, а просто считаете, сколько раз должен выполниться цикл, это нормально:
for (int i = 0; i < сount; i++)
{ … }

2) В лямбда-выражениях, где имя коллекции делает переменную x очевидной:
// Это хорошая альтернатива
int max = forecasts.Max(x => x.Temperature);
// этому
int max = forecasts.Max(
forecast => forecast.Temperature);

Практически во всех других случаях, кроме перечисленных выше, использование однобуквенных переменных вызовет недовольство ваших коллег. Если у вас цепочка выражений LINQ, данные часто изменяются по сравнению с первоначальным типом, с которого началась цепочка. В отличие от Fluent- API, где возвращаемое значение часто имеет тот же тип, что и все методы в цепочке, в LINQ возвращаются разные объекты. И типы этих объектов имеют значение. Вот не слишком сложный пример, который показывает, что даже в простых случаях было бы лучше яснее именовать переменные:
var maxTemperatures =
allTemperatures
.GroupBy(x => x.DayOfWeek)
.Select(y =>
new {
DayOfWeek = y.Key,
HighTemp = y.Max(z => z.Temperature)
})
.OrderBy(o => o.HighTemp)
.ToList();

x, y, z и o все разных типов. Даже если использовать g для группировки, есть риск, что она будет интерпретирована неверно.

Окончание следует…

Источник:
https://brendoneus.com/post/Ways-Of-Making-CSharp-Harder/
👍16
День 1472. #ВредныеСоветы
11 Способов Усложнить Себе Жизнь в C#. Окончание
1-2, 3-4, 5-6, 7-8

9. Сильно вложенный код
Хотите быстрый и простой способ сделать код труднее для чтения? Вложите условные операторы друг в друга несколько раз, проверяя каждое условие отдельно вместо использования return, && или ?. и ?? для null:
if (building != null)
{
if (building.Office != null)
{
if (building.Office.IsAvailable)
{
if (user.CanReserve)
{

}
}
}
}

Вы могли бы просто написать следующее:
if (building?.Office?.IsAvailable == true 
&& user.CanReserve)
{

}

Заметьте явное сравнение с true, т.к. оператор ?. возвращает bool? (Nullable<bool>), а не bool.

10. Использование интерфейса «один к одному» для класса модели
Когда люди узнают об инверсии зависимостей и моках, они бросаются в крайности, добавляя интерфейс к каждому классу независимо от того, будет ли несколько реализаций интерфейса или необходимо ли будет его мокать.

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

Проблема, если вы создаёте IStudent для ученика, ITeacher для учителя и ILesson для урока. Ни один из этих объектов, скорее всего, не нуждается в моке для тестирования, поскольку в тестах вы можете просто создать экземпляры этих моделей. Полезным может быть интерфейс вроде ISchoolMember для учащихся, учителей и администраторов, когда для всех требуется свойство SchoolID.

11. Размещение регионов внутри методов
Худшее я приберёг напоследок. Не буду стыдить за использование регионов в коде, однако почти всегда их лучше заменить изменением кода. Многим нравится отделять блоки кода регионами, но регион внутри метода должен иметь действительно вескую причину для существования. Помечая блок кода регионом, вы кричите о том, что его надо извлечь в метод:
public ProcessResult Update(ChangeLog changes)
{
#region Validate
if (changes == null)
throw ArgumentException(changes);

if (…)
throw …;
#end region

#region Log
logger.Debug(changes);

#endregion


}

Вместо регионов просто создайте отдельные методы для этих блоков:
public ProcessResult Update(ChangeLog changes)
{
Validate(changes);
Log(changes);

}

Источник: https://brendoneus.com/post/Ways-Of-Making-CSharp-Harder/
👍20
День 1473. #юмор
👍5
День 1474. #Карьера
Улучшаем Эмоциональный Интеллект. Часть 8
Эмоциональный интеллект – это способность понимать эмоции и управлять ими, бесценное качество, которое поможет стать более продуктивными и улучшить отношения с другими. Вот простые правила, которые помогут развить ваш эмоциональный интеллект.

8. Правило убеждения
Пытаетесь ли вы продать продукт, идею или даже себя, вы занимаетесь убеждением. В самом простом смысле - вы пытаетесь добиться своего.

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

Есть способ лучше, который можно назвать «аргументация с эмпатией».
Первый шаг к долговременным отношениям — это признать, что вы не можете заставить человека делать то, чего он не хочет, — по крайней мере, в долгосрочной перспективе, и чтобы он потом не пожалел об этом.

Значит ключ к тому, чтобы добиться своего, в том, чтобы не пытаться обмануть человека. Чтобы заставить партнёра задуматься над тем, что вы хотите сказать вам нужно ответить на три его вопроса:
- Ну и что?
- Какая разница?
- Что в этом для меня?

Предположим, вы пытаетесь продать онлайн-курс. Вы можете расписывать, сколько там часов видео и какая красивая графика. Но мало кому нравится просто проходить курс. Всех интересует конечный результат. Поможет ли курс стать лучше и желательно побыстрее?

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

1. Задавайте стратегические вопросы.
Чем больше вы узнаете о партнёре по переговорам и его точке зрения, тем лучше вы сможете адаптировать свои аргументы. В то же время ваши вопросы помогут им задуматься над своей точкой зрения, чего они, возможно, никогда не делали:
Какая ваша самая большая проблема прямо сейчас? Почему вы так говорите?
Что мешает вам преодолеть эту трудность? Вы всегда так чувствовали? Если нет, когда это началось?

2. Предоставьте доказательства.
Разных людей убеждают разные виды доказательств. Что касается вашего партнёра, спросите себя:
К кому он обращается за вдохновением? Что читает или смотрит? Чье мнение уважает?
Используйте ответы на эти вопросы, чтобы найти поддержку своей точки зрения. Ищите данные, мнения или даже отзывы из источников, которые они, скорее всего, будут уважать. Будьте осторожны, чтобы не ошибиться в цитатах и не вырывать информацию из контекста, что подорвёт доверие к вам.
Всё это позволит вам представить доказательства таким образом, который будет более привлекательным для вашего партнёра, вместо того, чтобы тратить время на аргументы, которые он вряд ли примет во внимание.

3. Знайте, когда уступить.
В ходе обсуждения вы можете увидеть ключевые недостатки в позиции другого человека. По мере того, как вы укрепляете доверие, вы можете тактично помочь человеку рассмотреть альтернативу его нынешнему образу мыслей.
Но помните: люди эмоционально привязаны к своим убеждениям. Если вы будете безжалостно разрушать каждый аргумент партнёра, он почувствует себя атакованным. Эмоции возьмут верх, и его внимание больше не будет сосредоточено на разумном обсуждении; он будет защищаться или атаковать в ответ.
Вместо того, чтобы пытаться доминировать, сосредоточьтесь на понимании другого человека. Затем на нахождении точек соприкосновения с целью заложить основу, на которую вы сможете опираться позже. Прежде всего, постарайтесь закончить разговор на позитивной ноте.
В конце концов, иногда убеждение — это игра в долгую.
Помните, единственный, кто может изменить мнение человека, — это сам человек. Ваша задача — просто помочь ему понять, почему он должен задуматься об этом. Потому что цель всех великих мастеров убеждения — не манипулирование, не обман и даже победа в спора, а партнёрство.

Источник: https://www.inc.com/justin-bariso/how-to-increase-emotional-intelligence.html
👍9
День 1475. #ЗаметкиНаПолях
Стратегии Кэширования на Стороне Сервера. Начало
Кэширование — это технология, позволяющая хранить данные таким образом, чтобы доступ к ним был невероятно эффективным. Более быстрое чтение приводит к увеличению скорости работы приложений, поэтому почти каждое приложение, которое должно обеспечивать высокую производительность, использует какой-либо тип кэша.

Кэширование существует на разных уровнях
- Уровень клиента (например, в браузере), чтобы избежать лишних обращений к серверу: так кэшируются изображения, файлы CSS и JavaScript.
- Уровень инфраструктуры (например, CDN). CDN — эффективный способ хранения статических ресурсов: браузерам по-прежнему приходится обращаться к серверу для их загрузки, но вместо вызова «основного» приложения они вызывают CDN для получения статических ресурсов, позволяя основному приложению обрабатывать запросы, требующие динамических данных.
- Уровень приложения. Если вам нужно обслуживать данные, которые не меняются очень часто, вы можете кэшировать их, чтобы избежать лишних обращений к источнику данных, которым обычно является БД или внешний API.

Рассмотрим самые распространённые стратегии кэширования в приложении.

1. Сторонний кэш (Cache-aside): кэш и БД не взаимодействуют
Cache-aside или ленивое кэширование используется наиболее часто. Читаем из кэша; если элемент не существует, извлекаем его из источника и добавляем в кэш, чтобы в следующий раз, когда приложение попытается извлечь тот же элемент, он уже присутствовал в кэше.

Преимущества
- Отлично подходит для рабочих нагрузок с большим объёмом чтения: каждый раз, когда происходит промах кэша, вы добавляете недостающие данные в кэш, поэтому при следующей попытке доступа к тем же данным они уже будут доступны.
- Если кэш недоступен, приложение всё равно работает: вместо того, чтобы запрашивать кэш, придётся каждый раз обращаться к БД; приложение станет медленнее, но будет работать.
- Не всё должно быть в кэше: используя Cache-aside, вы храните в кэше только те данные, которые кому-то нужны.

Недостатки
- Первый доступ будет медленнее (придётся вызывать и кэш, и БД).
- Если данные в БД меняются (например, из-за того, что другое приложение обновляет те же таблицы), у вас будут противоречивые данные — это означает, что вы должны найти способ вытеснять из кэша данные, обновлённые другими сервисами.

2. Сквозное чтение (Read-through): кеш знает, как запрашивать БД
В кэше есть компонент, который позволяет ему обращаться к БД и извлекать недостающие данные.

Для популярных систем кэширования, вроде Redis, существуют плагины, позволяющие им обращаться к БД. Другие системы, такие как NCache, позволяют вам реализовать такие модули в вашем приложении. Для NCache вы можете создать класс, который реализует IReadThruProvider, и настроить NCache для использования его при попытке чтения данных.

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

Недостатки
- Единая точка отказа. Каждый раз, когда нужно получить какие-то данные, они должны пройти через кэш. Если по какой-то причине кэш недоступен, приложение не сможет получить данные.
- Тесная связь между кэшем и БД: если модель в БД изменится, мы должны обновить код запроса к БД в кэше.

Окончание следует…

Источник:
https://www.code4it.dev/architecture-notes/caching-strategies
👍12
День 1476. #ЗаметкиНаПолях
Стратегии Кэширования на Стороне Сервера. Окончание
Начало

3. Сквозная запись (Write-through): кэш может записывать в БД СИНХРОННО
Данные сначала записываются в кэш, а затем синхронно в источник.

Приложение просит кэш сохранить некоторые данные. Кэш сохраняет эти данные в своём внутреннем хранилище, а затем записывает в БД, используя плагины и настройки. Затем, когда и кэш, и БД обновят значение, происходит возврат к приложению с результатом выполнения сохранения (успех/неудача). Приложение не записывает данные напрямую в БД, а сам кэш знает, как записывать данные в БД.

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

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

4. Отложенная запись (Write-behind): кэш может писать в БД АСИНХРОННО
Отложенная запись аналогична сквозной записи, но все операции записи в источник выполняются асинхронно.

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

Недостатки
- Аналогично сквозному чтению и сквозной записи, мы ввели единую точку отказа. Если кэш выходит из строя, данные не сохраняются в БД.
- Если кэш правильно обновляет своё внутреннее состояние, но по какой-то причине БД не сможет обновить данные, у нас будут несогласованные данные. И приложение не узнает, правильно ли данные были сохранены в БД.

Источник: https://www.code4it.dev/architecture-notes/caching-strategies
👍9
День 1477. #ЧтоНовенького
Проверка Орфографии Доступна в Visual Studio в Превью Версии
Visual Studio 17.5 превью 3 представляет первую предварительную версию средства проверки орфографии для файлов C#, C++ и Markdown.

Функция будет включена автоматически при работе с любым файлом C#, C++ или Markdown. Теперь, когда вы работаете с документом, поддерживаемым средством проверки орфографии, VS будет помечать любые обнаруженные слова как слова с ошибками. VS также предложит альтернативные варианты написания и поможет в исправлении, выполнив контекстное переименование, если ошибки допущены в идентификаторах. Проверку орфографии можно отключить, сняв флажок Text spell checker (Проверка орфографии в тексте) в разделе Manage Preview Features (Управление функциями в превью). Проверка орфографии также может быть включена или отключена из меню с помощью команды Edit > Advanced > Toggle Text Spell Checker (Правка > Дополнительно > Переключить Проверку Орфографии) или с помощью кнопки на главной панели инструментов в Visual Studio.

Исправить ошибки можно в панели быстрых действий, нажав Ctrl+. или Alt+Enter. Будет предложено три варианта решения. Если какой-либо из словарей предлагает варианты, Visual Studio предоставит их. Если варианты есть в нескольких словарях, предложения будут сгруппированы по словарю.
Строки и комментарии будут заменены однократно в одном месте. Исправление идентификатора в C++ или C# приведёт к рефакторингу/переименованию всех экземпляров идентификатора. Если вы выберете вариант проигнорировать ошибку, VS создаст файл excclusion.dic в вашем каталоге AppData на локальном компьютере, и это слово будет игнорироваться во всех экземплярах VS.

Поскольку C#, C++ и Markdown используют английский язык для ключевых слов, будет использован словарь “English (United States)” (en-us). Также VS возьмёт язык, используемый в Windows, и, если он отличается от “en-us”, этот словарь будет добавлен.

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

Настройка
Настроить проверку орфографии можно в editorconfig. Это позволяет установить стандарты кодирования, которые будут соблюдаться и поддерживать согласованность, что было бы затруднительно с помощью других методов. Вот что можно настроить в editorconfig:
1. Языки
spelling_languages = _language_[,_language_]
(Например: = en-us,fr-fr)
Здесь будут использованы только словари en-us и fr-fr. При этом языковой пакет fr-fr должен быть установлен на компьютере пользователя, иначе любые французские слова будут помечены как орфографические ошибки.

2. Типы для проверки
spelling_checkable_types = strings,identifiers,comments
(Например: = identifiers,comments)
Определяет, что VS должна проверять. Здесь будут проверяться идентификаторы и комментарии, а строки не будут.

3. Уровень предупреждений
spelling_error_severity = error|warning|information|hint
(Например: = error)
В этом примере орфографические ошибки будут отображаться как ошибки.

4. Путь к словарю исключений
spelling_exclusion_path = абсолютный или относительный путь.
(Example: = .\exclusion.dic)
В этом примере при первом запуске средства проверки орфографии для любого файла в решении Visual Studio проверит наличие файла exclusion.dic в том же каталоге, что и файл .sln (для проекта C#), или в корневом каталоге (для каталога C++). Если файла нет, программа проверки орфографии создаст его. Всякий раз, когда пользователь решит игнорировать слово, оно будет добавлено в файл excclusion.dic. Visual Studio будет рассматривать любое слово, которое появляется в excclusion.dic, как правильно написанное. Обратите внимание, что файл должен быть в кодировке UTF16 с BOM для правильной работы.

Источник: https://devblogs.microsoft.com/visualstudio/visual-studio-spell-checker-preview-now-available/
👍9
День 1478. #ЗаметкиНаПолях #DesignPatterns
Паттерн Сервис/Репозиторий
Идея паттерна заключается в том, что код верхнего уровня должен полностью игнорировать бизнес-уровень и уровень данных приложения. То есть, если вы запрашиваете заказ, ваш код должен выглядеть примерно так:
var order = orderService.GetOrder(12);

Что делает GetOrder, не важно. Это ответственность сервиса. Хотя, там может быть что-то такое (здесь и далее псевдокод):
GetSalesOrder(id) {
var order = repo.GetOrder(id);

if (order.HasAlert())
notifyService.SendAlert(order.Id);

return order;
}

Сервис предоставляет некоторый функционал: получает заказ из репозитория, а затем, например, отправляет уведомление.
Посмотрим на метод репозитория:
GetSalesOrder(id) {
var order = DB.RunSql(
"SELECT * FROM orders WHERE id = @id",
id);

var customer = DB.RunSql(
"SELECT * FROM customers WHERE id = @CustomerId",
order.CustomerId);

return new Order(order, customer);
}

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

Что даёт этот паттерн? Типичный ответ: вы «можете захотеть сменить СУБД». На самом деле, это крайне маловероятно. Гораздо более вероятно, что вы захотите повторно использовать репозиторий в другом месте (возможно, из другого сервиса).

Особенности использования
1. Двойной репозиторий
Чаще всего это случается при использовании Entity Framework, который сам по себе является репозиторием. Использовать EF внутри репозитория обычно бесполезно, но бывают случаи, когда это имеет смысл. Например, если вы решили переключиться с EF на Dapper, нужно взять контекст БД, который использует сервис, и заменить его репозиторием.

2. Сквозной сервис
Рассмотрим следующий код метода сервиса:
GetSalesOrder(id) {
return repo.GetOrder(id);
}
В этом случае он абсолютно ничего не делает, просто предоставляет оболочку, которую вы можете использовать. Можно сказать, что так весь код будет согласованным (контроллер > сервис > репозиторий), но это создаёт кучу лишних классов и делает код менее понятным. Очевидно, идеальная ситуация, когда сервис предоставляет дополнительную бизнес-логику.

3. Утечка ответственности
Это ситуация, когда один уровень начинает брать на себя ответственность от следующего уровня. Причина в том, что вы добавляете сложность, разделяя код на слои, но тесно связываете их, так что репозиторий зависит от сервиса. Например:
GetSalesOrder(id) {
var order = repo.GetOrder(id);
if (order.Name.StartsWith("a"))
order.Notes = repo.GetNotes(id);

return order;
}
Это кажется безобидным: на основе полученных данных мы должны или не должны получать дополнительные данные. Ясно, что какие данные извлекаются и как, - это ответственность репозитория, а не сервиса. Если мы рассматриваем примечания как особенность заказа, то везде, где извлекается заказ, потребуется эта логика. Т.е. вы не сможете вызвать репозиторий без сервиса. Если сервис и репозиторий связаны, зачем поддерживать два уровня абстракции?

Более очевидный пример:
CreateOrder(order, orderLines) {
repo.StartTransaction();
repo.CreateOrder(order);
repo.CreateOrderLines(orderLines);
repo.CommitTransaction();
}
Очевидно, что транзакция принадлежит репозиторию и не имеет никакого отношения к сервису.

4. Внешний доступ
Представим, что мы вызываем внешний API. Конечно, этот вызов следует рассматривать так же, как вызов базы данных (в обоих случаях используются внешние для приложения зависимости). Почему бы не создать репозиторий, который бы вызывал API и обрабатывал его ответы так же, как если бы данные извлекались из базы? Таким образом, остальная часть системы остаётся полностью независимой от источника данных, и вы сможете поменять его в любое время.

Источник: https://pmichaels.net/service-repository-pattern/
👍9