.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
День 1820. #ЧтоНовенького
NuGetSolver: Разрешение Конфликтов Зависимостей в Visual Studio

Microsoft представили новый экспериментальный инструмент NuGetSolver. Это расширение Visual Studio было создано совместно с Microsoft Research. Цель — упростить разрешение конфликтов зависимостей NuGet в проектах Visual Studio. Расширение эффективно устраняет распространённые ошибки и предупреждения NuGet, такие как ограничения зависимостей между пакетами (NU1107), случаи, когда пакет зависимостей не содержит ресурсов, совместимых с проектом (NU1202), обнаруженные понижения версии пакета (NU1605), и предупреждения о несовместимости версий (NU1701).

Чтобы начать использовать NuGetSolver, разработчики могут загрузить расширение из Visual Studio Marketplace. Расширение предлагает решение исследуя все зависимости и предоставляя интеллектуальные и автоматизированные предложения. Доступ к этому инструменту можно получить через обозреватель решений, щёлкнув правой кнопкой мыши и выбрав Resolve Dependency Conflicts (Разрешить конфликты зависимостей). Инструмент отобразит различия между текущим и предлагаемым состояниями. Пользователи также могут включить флажок Show only changes (Показать только изменения), чтобы просмотреть полный список зависимостей. По умолчанию инструмент предлагает стабильные версии с возможностью включения предварительных версий при необходимости. Если рекомендуемое предложение приемлемо для разработчика, нужно нажать кнопку Apply fix (Применить исправление) и пересобрать решение.

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

Если в решении в настоящее время отсутствуют конфликты зависимостей, разработчики всё равно могут запустить инструмент для эффективного обновления зависимостей, минимизируя изменения. Это оказывается более быстрой и надёжной альтернативой обновлению пакетов по одному с помощью менеджера пакетов NuGet.

Однако существуют некоторые рекомендации по использованию и известные ограничения:
1. В настоящее время поддерживается только канал nuget.org.
2. Исправление может не полностью поддерживать обновление версий, если для настроек версии используется пользовательская логика MSBuild.
3. NuGetSolver может не учитывать все доступные предварительные версии во время расчёта предложений.
4. Для проектов, использующих packages.config или устаревшие sdk, инструмент может генерировать предложения, но не может применить исправление автоматически, требуется исправление вручную.
5. Хотя NuGetSolver может разрешать конфликты зависимостей во время компиляции, ошибки во время выполнения все равно могут возникать.
6. Инструмент не проверяет наличие известных уязвимостей в предлагаемых версиях, поэтому разработчикам рекомендуется использовать функцию аудита в NuGet для решения этой проблемы.

Источник: https://www.infoq.com/news/2024/01/introducing-nuget-solver/
👍11
День 1821. #ЗаметкиНаПолях
Разница Mежду CultureInfo.Get и new CultureInfo

Если вы хотите получить объект CultureInfo, вы можете использовать статический метод CultureInfo.GetCultureInfo или конструктор класса CultureInfo. Рассмотрим разницу между ними.

var c1 = CultureInfo.GetCultureInfo("en-US");
var c2 = new CultureInfo("en-US");

Конструктор создает новый экземпляр указанной культуры. Вы можете редактировать данные этого экземпляра. Это означает, что вы можете изменить календарь, числовой формат и т. д. Следующий код показывает, как изменить символ валюты:
var c = new CultureInfo("en-US");
c.NumberFormat.CurrencySymbol = "€";

Console.WriteLine(42.ToString("C", c));
// €42.00


Статический метод CultureInfo.GetCultureInfo возвращает доступный только для чтения экземпляр указанной культуры. Вы не можете редактировать данные этого экземпляра. И поэтому метод может кэшировать экземпляр. Таким образом, это может быть быстрее и уменьшить использование памяти.
var c1 = CultureInfo.GetCultureInfo("en-US");
var c2 = CultureInfo.GetCultureInfo("en-US");
Console.WriteLine(ReferenceEquals(c1, c2));
// True


Если выполнить простой тест производительности, можно увидеть разницу в распределении между двумя методами:
[MemoryDiagnoser]
public class CultureInfoBenchmark
{
[Benchmark(Baseline = true)]
public void Ctor()
{
_ = new CultureInfo("en-US");
}

[Benchmark]
public void StaticMethod()
{
_ = CultureInfo.GetCultureInfo("en-US");
}
}


Method        Mean      Allocated
Ctor 33.74 ns 144 B
StaticMethod 24.44 ns 32 B


Итого
Используйте CultureInfo.GetCultureInfo большую часть времени, поскольку редактирование объекта CultureInfo требуется очень редко.

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

Источник: https://www.meziantou.net/difference-between-cultureinfo-get-and-new-cultureinfo.htm
👍13
День 1822. #Карьера
6 Факторов, Определяющих Победите Вы или Провалитесь. Начало

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

Вот 6 факторов, которые не гарантируют успеха, но определённо помогут изменить баланс в вашу пользу.

1. Ясность критериев успеха
Если иметь лишь смутное представление о том, что для вас значит успех, может быть сложно определить, достигли ли вы своей цели. Достижение успеха начинается с определения того, что он для вас значит: что для вас важно, чего вы хотите достичь, почему это важно, как вы можете это измерить?

Определите успех, ответив на следующие вопросы:
- Как выглядит успех?
- Что изменится, когда вы достигнете этого?
- Что останется прежним, если вы не достигнете своей цели?
- Какие показатели, параметры или другие данные необходимы для отслеживания вашего прогресса?
- Как узнать, находитесь ли вы на правильном пути, а когда отклонились от него?

Будьте ясны, кратки и конкретны. Расплывчатые определения, такие как счастливая семья, успешная карьера, финансовая безопасность, только заставят вас чувствовать себя застрявшим, несчастным и неудовлетворенным.

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

Вот несколько важных практик, которые помогут достичь ежедневных целей:

- Разбейте цель на небольшие задачи. Маленькие шаги отключают систему сигнализации мозга, которая сопротивляется переменам и боится их.
- Работая над задачей, используйте «помидорный график».
- Запланируйте самые важные задачи на пик вашей умственной энергии.
- В конце каждого дня выделяйте 15–20 минут, чтобы поразмышлять о прогрессе и определить, как его можно улучшить.

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

При столкновении с препятствием:

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

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

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

Источник:
https://betterprogramming.pub/6-factors-that-determine-whether-you-will-succeed-or-fail-ae1dfe446e2b
👍9
День 1823. #Карьера
6 Факторов, Определяющих Победите Вы или Провалитесь. Окончание

Начало

4. История, которую вы рассказываете себе
Ваш разум — это машина, создающая смыслы. Ему нравится объяснять вещи, придумывая истории, которые соответствуют вашим убеждениям и ожиданиям.
Когда вы чего-то достигаете, учитываете ли вы роль внутренних факторов, таких как ваши усилия, навыки и упорство, которые способствовали этому успеху, или вы игнорируете свои достижения, приписывая их внешним факторам, таким как удача, другие люди или стечение обстоятельств? Аналогично, когда вы терпите неудачу, как вы реагируете? Берёте ли вы на себя ответственность и анализируете своё поведение или обвиняете внешние обстоятельства или других людей?

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

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

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

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

Критика может быть неприятна, но она необходима. Она выполняет ту же функцию, что и боль - привлекает внимание к проблеме.

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

Когда обращаетесь за помощью:
- Прямо попросите о помощи. Не думайте, что другие могут читать ваши мысли.
- Излагайте проблему конкретно и чётко.

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

Источник: https://betterprogramming.pub/6-factors-that-determine-whether-you-will-succeed-or-fail-ae1dfe446e2b
👍8
День 1824. #ЧтоНовенького
MSTest Runner

Microsoft представили MSTest Runner, небольшую утилиту для запуска тестов под MSTest. Основная цель — повысить переносимость, надёжность и скорость, одновременно предоставляя пользователям расширяемые возможности тестирования.

MSTest Runner представлен как независимый переносимый исполняемый файл с упором на устранение необходимости во внешних инструментах, таких как vstest.console, dotnet test или Visual Studio, для выполнения тестов. Команда разработчиков считает, что он подходит для разработки тестов на устройствах с ограниченной мощностью или объёмом памяти, предлагая упрощённое решение для тестирования.

MSTest Runner поставляется в комплекте с NuGet-пакетом MSTest.TestAdapter, начиная с версии 3.2.0.

По сравнению с VSTest, MSTest Runner предлагает несколько преимуществ:
1) Портативность
Упрощает выполнение тестов, запуская тесты непосредственно из исполняемого файла, устраняя сложности, связанные с традиционной инфраструктурой тестирования. С помощью MSTest Runner проекты рассматриваются как обычные объекты, что позволяет разработчикам использовать существующие инструменты dotnet и запускать тесты на разных компьютерах без дополнительной настройки.
Сообщается, что существует план добиться поддержки NativeAOT. Кроме того, на GitHub представлен пример запуска тестов для приложения dotnet, размещённого в Docker, где нет полноценного .NET SDK.

2) Производительность
MSTest Runner оптимизирует использование ресурсов на серверах сборки, по сравнению с dotnet test. Как заявила команда разработчиков, во внутренних проектах Microsoft, внедривших MSTest Runner, наблюдалась существенная экономия в использовании ЦП и памяти, при этом некоторые проекты завершали тесты в три раза быстрее, используя при этом в четыре раза меньше памяти по сравнению с dotnet test.
Также MSTest Runner вводит новые настройки по умолчанию, отдающие приоритет безопасности и снижающие вероятность случайного пропуска выполнения теста. Кроме того, благодаря своей архитектуре без сканирования папок, динамической загрузки или рефлексии для обнаружения расширений гарантирует согласованное поведение как в локальной среде, так и в среде CI. А асинхронная природа утилиты сводит к минимуму зависания и взаимоблокировки, устраняя распространённые проблемы, наблюдаемые при использовании VSTest.

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

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

Источник: https://www.infoq.com/news/2024/01/introducing-new-ms-test-runner/
👍8👎3
День 1825. #ЗаметкиНаПолях
Короткие URL в .NET. Начало

Короткие URL - простой, но мощный инструмент, преобразующий длинные URL в более удобные и короткие. Два популярных инструмента сокращения URL-адресов — Bitly и TinyURL. Посмотрим, как создать его самому.

Нам нужны 2 конечные точки:
- Генерирующая уникальный кода для данного URL,
- Перенаправляющая с короткой ссылки, на исходный URL.
URL будут храниться в БД.

Длина кода и набор символов определяют, сколько коротких URL может сгенерировать система. Для генерации будем использовать Random, т.к. его легко реализовать, и он имеет приемлемо низкий уровень коллизий.

Модель данных
ShortUrl представляет URL, хранящиеся в нашей системе:
public class ShortUrl
{
public Guid Id { get; set; }
public string Url { get; set; }
public string Code { get; set; }
public DateTime CreatedOn { get; set; }
}

Класс включает исходный URL (Url) и уникальный код (Code), представляющий сокращённый URL. Id и CreatedOn используются для БД и отслеживания.

В AppDbContext настроим сущность и контекст БД:
- Максимальную длину кода,
- Уникальный индекс на столбце Code, чтобы в БД не было повторяющихся значений кода.
- Также некоторые БД обрабатывают строки без учета регистра. Это значительно уменьшает количество доступных коротких URL. Нужно настроить БД для обработки уникального кода с учетом регистра:
public class AppDbContext : DbContext
{
public AppDbContext(DbContextOptions opts)
: base(options)
{ }

public DbSet<ShortUrl> ShortUrls { get; set; }

protected override void
OnModelCreating(ModelBuilder mb)
{
mb.Entity<ShortUrl>(b =>
{
b.Property(u => u.Code)
.HasMaxLength(ShortLinkSettings.Length);

b.HasIndex(u => u.Code)
.IsUnique();
});
}
}


Генерация уникального кода
Есть несколько алгоритмов реализации. Мы хотим равномерного распределения уникальных кодов по всем возможным значениям. Это поможет уменьшить коллизии. Здесь рассмотрим генератор случайного кода с предопределённым алфавитом. Его просто реализовать, и вероятность коллизий относительно невелика. ShortLinkSettings содержит две константы - длину кода и алфавит:
public static class ShortLinkSettings
{
public const int Length = 7;
public const string Alphabet =
"ABCDEF…xyz01…89";
}

В алфавите 62 символа, что даёт больше 3х триллионов(!!!) уникальных комбинаций.

UrlShorteningService генерирует уникальные коды. Мы выбираем случайные символы из алфавита до достижения длины, а затем проверяем, нет ли уже такого кода в БД. Если нет, возвращаем его, если есть, повторяем процесс:
public class UrlShorteningService(AppDbContext ctx)
{
private Random _rnd = new();

public async Task<string> GetCode()
{
const len = ShortLinkSettings.Length;
var chars = new char[len];
const int maxVal =
ShortLinkSettings.Alphabet.Length;

while (true)
{
for (var i = 0; i < len; i++)
{
var idx = _rnd.Next(maxVal);
chars[i] =
ShortLinkSettings.Alphabet[idx];
}

var code = new string(chars);
if (!await ctx.ShortUrls.AnyAsync(
s => s.Code == code))
return code;
}
}


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

Источник:
https://www.milanjovanovic.tech/blog/how-to-build-a-url-shortener-with-dotnet
👍16
День 1826. #ЗаметкиНаПолях
Короткие URL в .NET. Окончание

Начало

Теперь создадим конечные точки для минимального API.
Первая принимает URL, создаёт короткий URL и возвращает его:
app.MapPost("shorten", async (
string url,
UrlShorteningService svc,
AppDbContext dbCtx,
HttpContext httpCtx) =>
{
if (!Uri.TryCreate(url, UriKind.Absolute, out _))
return Results.BadRequest(
"Предоставленный URL неверный.");

var code = await svc.GetCode();
var req = httpCtx.Request;
var shortUrl = new ShortUrl
{
Id = Guid.NewGuid(),
Url = url,
Code = code,
CreatedOn = DateTime.UtcNow
};
dbCtx.ShortenedUrls.Add(shortUrl);
await dbCtx.SaveChangesAsync();
return Results.Ok(
$"{req.Scheme}://{req.Host}/{code}");
});

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

Вторая конечная точка перенаправит на исходный URL при доступе к сокращённому:
csharp 
app.MapGet("{code}",
async (
string code,
AppDbContext dbCtx) =>
{
var shortUrl = await
dbCtx.ShortUrls
.SingleOrDefaultAsync(
s => s.Code == code);

if (shortUrl is null)
return Results.NotFound();

return Results.Redirect(shortUrl.Url);
});

Эта конечная точка ищет код в БД и, если он найден, перенаправляет пользователя на исходный длинный URL. Ответ будет иметь код состояния 302 (Found) согласно стандартам HTTP.

Недостатки и улучшения
1. Недостатком реализации сервиса является длинная задержка, т.к. мы проверяем каждый генерируемый код в БД. Улучшением может стать заблаговременное создание уникальных кодов в БД.
2. Кэширование второй конечной точки позволит снизить нагрузку на БД для часто используемых коротких URL.

Источник: https://www.milanjovanovic.tech/blog/how-to-build-a-url-shortener-with-dotnet
👍7
День 1827.
Нам 5 лет!

А вас почти 4000. Спасибо, что читаете, лайкаете и комментируете.

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

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

Ещё раз спасибо, что читаете, а те, кто кроме этого хочет поддержать, добро пожаловать в Boosty или Patreon.
👍84👎1
.NET Разработчик pinned «День 1827. Нам 5 лет! А вас почти 4000. Спасибо, что читаете, лайкаете и комментируете. Для тех, кто пришёл недавно, вот здесь подборка тематических тегов. Либо вы просто можете поискать по сообщениям в канале то, что вам нужно. Также добро пожаловать в…»
День 1828. #ЧтоНовенького
Новые Функции Расширения Visual Studio GitHub Copilot

В последнем выпуске расширения Visual Studio GitHub Copilot Chat представлены две примечательные функции повышения производительности: команды с косой чертой и контекстные переменные. Кроме того, разработчики могут изучить несколько функций в превью-версии, такие как Помощник по исключениям, Анализ сбоев тестов, Рекомендации для выражений точек останова, Рекомендации по сообщениям коммита и многие другие.

Первым заметным дополнением является добавление команд с косой чертой, представляющих собой набор специализированных директив, которые разработчики могут использовать в интерфейсе чата для запуска определённых действий, связанных с кодом. Введено несколько команд:
- /doc добавит документацию в код.
- /explain даст подробное объяснение кода,
- /fix предложит решения выявленных проблем в выбранном коде,
- /generate запустит Copilot для создания кода по запросу,
- /help откроет помощь в Copilot Chat,
- /optimize проанализирует и улучшит время выполнения выбранного кода,
- /tests создаст модульные тесты для выбранного кода.

Другая примечательная новинка - функция контекстных переменных, которая позволяет разработчикам легко включать в вопросы файлы из решения, используя символ #. Это позволяет Copilot получать доступ к содержимому файлов, на которые имеются ссылки, и предоставлять более целенаправленные ответы. Например, разработчики могут задать вопрос о функциональности определённого файла, например #Main.cs, и получить соответствующую информацию в чате Copilot. Обратите внимание, что в один вопрос можно включить несколько файлов. В ответах будут видны ссылки на добавленные файлы. Нажатие на эти ссылки перенаправит пользователей к их содержимому, предлагая удобный способ навигации и понимания файлов, на которые имеются ссылки.

Также доступно несколько экспериментальных функций в превью-версии.
- Ассистент по исключениям в отладчике автоматически добавит ссылку Ask Copilot (Спросить Copilot) в окно сообщения об ошибке при отладке.
- Solution Reference (Справочник решения), позволяющий пользователям находить ссылки на элементы кода в решении и перемещаться по ним. При использовании директивы #solution, вы дадите Copilot команду добавить код решения в контекст вопроса и предложить более точное решение.
- Предложения в профилировщике производительности проанализируют данные о производительности, собранные профилировщиком производительности Visual Studio, и покажут рекомендации по оптимизации скорости кода, использования памяти и скорости ответа.
- Анализ сбоев тестов поможет отлаживать и исправлять сбои модульных тестов. Copilot предоставит вам полезную информацию о сбое теста, такую как сообщение с утверждения, ожидаемые и фактические значения, исходный код и возможные решения.

Отзывы сообщества о Visual Studio Copilot Chat в целом положительные: пользователи хвалят такие функции, как #solution. Однако есть и проблемы с некоторыми командами с косой чертой, такими как /doc для больших блоков кода, а также слишком общий характер описаний в /explain. Пользователи предлагают варианты настройки, такие как выбор языка для сообщений коммита. Есть также предложения относительно будущих улучшений, таких как возможности мониторинга и выражения эмоций.

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

Для использования Visual Studio Copilot Chat нужно использовать Visual Studio 2022 версии 17.8 или выше. Кроме того, необходимо убедиться, что учётная запись GitHub, с которой выполнен вход в Visual Studio, связана с активной подпиской GitHub Copilot.

Источник: https://www.infoq.com/news/2024/01/vs-github-copilot-new-features/
👍4👎2
День 1829. #Карьера
Когда Начальник Вас не Слушает

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

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

2. Начальник игнорирует мои идеи
Упорно работать над чем-то может показаться деморализующим, если начальство игнорирует ваш вклад и выбирает совершенно другое направление.
В таких случаях может помочь переоценка вашей презентации. Постарайтесь найти наиболее важную часть вашей идеи и договориться о ней, вместо того чтобы настаивать на полном пакете.
Сосредоточьтесь на чём-то, что принесет ощутимые результаты для бизнеса либо напрямую (за счет зарабатывания денег), либо косвенно (например, за счет снижения затрат или повышения эффективности). Если возможно, создайте доказательство концепции и измерьте результат. Представьте эти результаты руководителю.

3. Начальник не помогает с проблемами по работе
Всего 23% сотрудников сообщают, что их руководитель всегда конструктивно реагирует, когда они делятся своими рабочими проблемами, а 17% утверждают, что их руководитель вообще им не помогает.
Постарайтесь разобраться в проблеме. Может у него много дел, и нет времени вам помочь. Тогда предложите свою помощь в каких-то вопросах.
Ещё одна причина, может быть в том, что начальник хочет, чтобы вы сами нашли решение и получили опыт. Если вы исчерпали все возможные варианты и не знаете, как двигаться дальше, важно подчеркнуть это.

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

Поднимите проблему
Не уклоняйтесь от обсуждения проблем и не позволяйте проблеме накапливаться. Относитесь к этому так же, как к любой обратной связи; давайте её своевременно и привяжите к конкретным фактам. Какое именно поведение начальства заставило вас почувствовать, что вас игнорируют? Соблазнительно начать жаловаться, но полезнее переключиться в режим решения проблем. Подумайте, как вы можете быть наиболее полезны для бизнеса.

Говорить ли с начальством начальства?
Иногда может возникнуть соблазн переступить через голову. Прежде чем делать это, учтите последствия. Это необратимо повлияет на ваши отношения. Даже если вы добьётесь своего, после этого вашему руководителю будет трудно вам доверять. В некоторых компаниях начальник вашего руководителя наотрез откажется с вами разговаривать, вам могут сделать выговор или даже уволить. Это можно делать, только если произойдёт что-то неэтичное или незаконное.

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

Источник: https://betterprogramming.pub/when-your-manager-does-not-listen-55875a35c974
👍10👎2
День 1830. #ЗаметкиНаПолях
Проверяем, Пустая ли Коллекция в C#
В C# существуют разные способы проверить, пустая ли коллекция. В зависимости от типа коллекции вы можете проверить свойства Length, Count или IsEmpty. Также можно использовать метод расширения Enumerable.Any().
// массив: Length
int[] array = ...;
var isEmpty = array.Length == 0;

// List: Count
List<int> list = ...;
var isEmpty = list.Count == 0;

// ImmutableArray<T>: IsEmpty
ImmutableArray<int> immArray = ...;
var isEmpty = immArray.IsEmpty;

// Span: IsEmpty
Span<int> span = ...;
var isEmpty = span.IsEmpty;

// метод расширения
List<int> list = ...;
var isEmpty = !list.Any();


В C# 11, вы можете использовать сопоставление с образцом, чтобы позволить компилятору использовать лучший метод для проверки того, пуста ли коллекция. Не нужно запоминать правильное имя свойства, можно использовать оператор is:
var collection = ...;
var isEmpty = collection is [];


Обратите внимание, что предыдущий код не совсем эквивалентен проверке свойства Length. Если экземпляру коллекции присвоить NULL, проверка свойства вызывает исключение NullReferenceException, а сопоставление с образцом вернёт false:
int[] array = null;
// NullReferenceException
var isEmpty = array.Length == 0;
// false
var isEmpty = array is [];


Проверить на null и пустую коллекцию, можно так:
var isNullOrEmpty = array is null or [];


Ту же логику можно использовать и для строк, хотя использование string.IsNullOrEmpty гораздо более распространено:
string str = "";
isEmpty = str is "";
isEmpty = str is [];


Источник: https://www.meziantou.net/checking-if-a-collection-is-empty-in-csharp.htm
👍37
День 1831. #ЧтоНовенького #CSharp13
Три новых метода LINQ в .NET 9

Продолжаем заглядывать в будущее .NET. Сегодня посмотрим, какие новые методы будут добавлены во всеми любимый LINQ.

CountBy
Многие функции LINQ имеют расширение By, в котором можно предоставить функцию выбора для группировки элементов. Например, MinBy, MaxBy, DistinctBy и т. д. Теперь у нас есть новый: CountBy. Он группирует элементы по функции селектора и возвращает перечисление KeyValuePairs. Ключ — это объект, а значение — количество элементов в группе.
public record Person(string FirstName, string LastName);

List<Person> people =
[
new("Steve", "Jobs"),
new("Steve", "Carell"),
new("Elon", "Musk")
];

foreach (var p in people.CountBy(p => p.FirstName))
Console.WriteLine($"{p.Value} людей с именем {p.Key}");

Вывод:
2 людей с именем Steve
1 людей с именем Elon


Index
Не то, чтоб совсем новинка, это можно делать и сейчас, но с другим синтаксисом. Index возвращает элемент и его индекс в коллекции:
foreach (var (index, item) in people.Index())
Console.WriteLine($"№{index}: {item}");


Сейчас такого можно добиться, используя перегрузку метода Select:
foreach (var (item, index) in 
people.Select((item, index) => (item, index)))
{
Console.WriteLine($"№{index}: {item}");
}

Интересно, что в методе Index решили поменять порядок индекса и элемента. Оказывается, это было осознанным решением команды дотнет: «Мы решили сначала возвращать индекс, а затем значение, потому что это кажется более естественным, несмотря на то, что существующий метод Select() сначала возвращает значение, а потом индекс.»

AggregateBy
Этот метод похож на CountBy, но вместо подсчёта элементов он их агрегирует. Вы можете предоставить начальное значение и функцию агрегирования. Функция получает текущее агрегированное значение и текущий элемент в качестве параметров и должна вернуть новое агрегированное значение.
public record Person(
string FirstName,
string Department,
int Salary);

List<Person> people =
[
new("Jobs", "Sales", 100),
new("Carell", "Sales", 120),
new("Musk", "IT", 290)
];

var aggregateBy = people.AggregateBy(
p => p.Department,
x => 0,
(x, y) => x + y.Salary
);
foreach (var kvp in aggregateBy)
Console.WriteLine($"ФОТ отдела {kvp.Key}: {kvp.Value}");

Вывод:
ФОТ отдела Sales: 220
ФОТ отдела IT: 290


Источник: https://steven-giesel.com/blogPost/0594ba85-356b-47f1-89a9-70e9761c582e/three-new-linq-methods-in-net-9
👍25
День 1832. #ЗаметкиНаПолях
.http-Файл в Visual Studio не Отправляет Заголовок Авторизации
При отправке запросов к API в Visual Studio возникает странная проблема. Bearer-токен, который в Swagger работает нормально, в файле .http просто игнорируется, что приводит к ошибке 401 Unauthorized.

Проблема
Простой проект Webapi ASP.NET Core, используя шаблон по умолчанию со встроенной поддержкой .http-файлов для выполнения запросов к проекту. Регистрация и вход в систему работают нормально, но попытка доступа к конечной точке, требующей аутентификации, всегда приводит к ошибке 401. Тот же токен, добавленный в тот же заголовок авторизации, отлично работает при использовании Swagger/Swashbuckle в браузере.

Диагностика проблемы
На вкладке Request info (Информация о запросе) в файле .http даже не отображался заголовок Authorization (но отображался кастомный заголовок Authorization2, который был идентичен во всех отношениях, кроме имени). Стало ясно, что это было так и задумано. Проблема в том, что запрос из .http-файла первоначально отправлялся на https://localhost:5206/cart, который перенаправлялся на https://localhost:7248/cart из-за использования промежуточного ПО UseHttpsRedirection.

Конечная точка http была настроена как переменная в верхней части файла .http, поэтому даже в самом файле не было очевидно, что данный запрос использует не тот URL/порт:
POST {{BaseUrl}}/cart


На вкладке Request (Запрос) вывода .http-файла отображался URL https://localhost:7248/cart, что никак не обозначает, что он неправильный (не тот, куда шёл изначальный запрос). Единственная проблема – отсутствие заголовка авторизации.

Возможно, было бы неплохо включить на вкладке Request (или где-то еще) информацию о том, что было выполнено перенаправление и что конечный URL не соответствует исходному запрошенному URL.

Заголовки перенаправления и авторизация
Основная проблема тут в том, как работает UseHttpsRedirection. Он отправляет клиенту в ответ заголовок перенаправления, и если клиент настроен на автоматическое следование перенаправлениям, он «молча» переходит на предложенный в перенаправлении URL. Однако также существует соглашение не пересылать заголовки авторизации при перенаправлениях:
«Заголовок Authorization очищается при автоматическом перенаправлении, и обработчик автоматически пытается повторно пройти аутентификацию на целевом URL. Никакие другие заголовки не очищаются. На практике это означает, что приложение не может помещать пользовательскую информацию аутентификации в заголовок Authorization, если есть возможность столкнуться с перенаправлением. Вместо этого приложение должно реализовать и зарегистрировать собственный модуль аутентификации.»

Обратите внимание, что в этом документе буквально говорится, что вам не следует использовать заголовки аутентификации, «если возможно столкнуться с перенаправлением», что, по сути, означает, что вы никогда не должны комбинировать UseHttpsRedirection с API, защищённым токеном.

Посмотрите предложение об изменении поведения файлов .http в Visual Studio и проголосуйте, если заинтересует.

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

Источник: https://ardalis.com/http-file-not-sending-auth-header/
👍17
День 1833. #ЗаметкиНаПолях
Обзор Инструментов Покрытия Кода для C#. Начало
В этой серии постов рассмотрим различные инструменты покрытия кода в .NET и перечислим их функции.

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

Что это и зачем?
Если коротко, измерения покрытия кода показывают, какие строки кода ваш набор тестов выполняет, а какие нет. Простой пример:
public int Divide(int x, int y)
{
if(y != 0)
return x / y;

return 0;
}

Допустим, это единственный метод в нашей кодовой базе, и мы написали один модульный тест, что Divide(2, 1) должно вернуть 2. Мы получим 67% покрытия кода, т.к. тест заставит среду проверить условие, и вернуть x/y, таким образом выполнив 2 строки метода из 3х.

Разработчики могут использовать анализ покрытия кода, чтобы увидеть дыры в своём тестировании. В примере выше анализ покрытия кода подскажет, что надо протестировать случай, когда y=0.

Инструменты
Практически в любом языке и технологическом стеке есть способы определить, насколько полно набор модульных тестов покрывает вашу кодовую базу. Однако не путайте покрытие кода с оценкой качества ваших тестов. Это просто мера объёма кода, проверяемого тестами. Следующие инструменты помогут вам оценить покрытие кода тестами в .NET.

1. Visual Studio Code Coverage
Если у вас корпоративная версия Visual Studio, вы можете воспользоваться этой возможностью «из коробки». Более подробно об этом можно прочитать на сайте документации Microsoft. Но это хороший, комплексный вариант, который требует совсем немного дополнительной работы, при условии, что у вас есть правильная версия. И у него есть интересные функции:
- Сообщает процент покрытия с различной степенью детализации (например, сборка, класс и т. д.).
- Вы можете выбрать все тесты или их подмножество.
- Подсветка кода в IDE, т.е. он показывает, какие строки кода покрыты тестами, когда вы смотрите на код.
- Продукт Microsoft, поэтому вы можете рассчитывать на обновления и поддержку.

2. dotCover в Rider и ReSharper
Если у вас есть лицензия Visual Studio Enterprise, ваша жизнь во многих отношениях хороша. Если нет, выкладывать $3000 в год только ради покрытия кода, наверное, перебор.
Другой вариант - JetBrains dotCover, который входит в предложения Jetbrains (от $349 до $779 в год). Вы получите анализ покрытия, а также Rider и ReSharper, которые являются действительно классными инструментами.
Некоторые основные функции dotCover:
- Подробная отчётность.
- Исполнители тестов. Тесты также можно запускать с помощью профилировщика dotTrace для измерения производительности.
- Интеграция измерений покрытия как в Visual Studio, так и в CI.
- Переход к покрывающим тестам.
- Хороший обзор «горячих точек», показывающий рискованные методы.
- Отрисовка зеленых/красных операторов в IDE.

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

Источник:
https://blog.ndepend.com/guide-code-coverage-tools/
👍1
День 1834. #ЗаметкиНаПолях
Обзор Инструментов Покрытия Кода для C#. Окончание

Начало

3. NCrunch
Предоставит вам данные о покрытии кода, а также подсветит покрытый и непокрытый тестами код в IDE. Кроме этого, NCrunch постоянно запускает ваши тесты в режиме реального времени по мере того, как вы печатаете. Это живое модульное тестирование. С NCrunch вам не нужно запускать тесты или даже компилировать код, чтобы получить информацию о том, нарушают ли что-нибудь ваши изменения в коде. Отметки о покрытии будут меняться по мере ввода.
Другие особенности:
- Небольшой и настраиваемый объем используемой памяти.
- Встроенные сведения об исключениях и простая отладка, интегрированная в VS.
- Безопасное многопроцессное параллельное выполнение тестов с возможностью масштабирования.
- Пассивный сбор данных как о покрытии кода, так и о производительности.
- Интеллектуальное выполнение, способное исполнять только те тесты, на которые влияют изменения.
- Очень быстрое выполнение тестов и возможность работать с очень большими наборами тестов.
Цены на NCrunch очень разумные: от $159 до $289 за лицензию для отдельного разработчика.

4. AltCover (ранее известный как OpenCover)
Вот уже несколько лет бесплатный инструмент с открытым кодом AltCover, разработанный на F# Стивом Гилхэмом, заменил известный инструмент OpenCover.
Особенности:
- Инструмент командной строки, предназначенный для сбора информации о покрытии кода .NET. Поддерживаются среды выполнения .NET Core, .NET Framework и Mono.
- Легко интегрируется с задачами MSBuild, предлагая надёжную поддержку для управления инструментом, включая полную интеграцию с функциями dotnet test.
- Предоставляет универсальный расширяемый API, который легко интегрируется с популярными инструментами автоматизации сборки, такими как Fake и Cake.
- Расширяет совместимость со средами PowerShell, предлагая специальный модуль, совместимый как с PowerShell 5.1, так и с PowerShell Core 6+.
- Включает специализированный инструмент визуализации покрытия, основанный на AvaloniaUI.

5. Coverlet
Coverlet — фреймворк покрытия кода, разработанный для .NET и предлагающий поддержку покрытия строк, ветвей и методов. Он совместим с .NET Framework и .NET Core на всех поддерживаемых платформах.
Особенности:
- Легкая интеграция в проекты .NET, не создавая при этом большой нагрузки на систему.
- Бесплатный и с открытым исходным кодом.
- Гибкая конфигурация в соответствии с конкретными требованиями и предпочтениями по покрытию кода.
- Предоставляет надёжную и подробную информацию о коде, помогая выявить области, требующие тестирования и улучшения.
Если вы используете Visual Studio Code, Coverlet станет отличным инструментом.

6. Fine Code Coverage
Бесплатное расширение Visual Studio, предназначенное для предоставления данных о покрытии в IDE. Оно работает со всеми выпусками Visual Studio, включая версию Community. Fine Code Coverage добавляет специальное окно в VS, в котором есть вкладки, предоставляющие ценную информацию о степени покрытия кода с разбитием на проекты и классы, а также подсветку покрытых строк кода.

Источник: https://blog.ndepend.com/guide-code-coverage-tools/
👍12👎1
День 1835. #ЗаметкиНаПолях
Пять Шагов по Управлению Легаси-Кодом. Начало
Работать с легаси-кодом не особо весело, но это неизбежно. Разработчик вы, технический руководитель или менеджер продукта, наступит момент, когда какая-то работа, которую вы хотите выполнить, будет связана с устаревшим кодом. Рассмотрим, что на самом деле означает устаревший код и как продумать возможные решения для улучшения состояния кодовой базы и способностей вашей команды эффективно поставлять функции.

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

2. Реалистичный подход к определению легаси-кода
Термин «устаревший код» часто используется, и для команды важно иметь чёткое определение, которое разделяет и понимает каждый. Старый код не обязательно является легаси-кодом. Понятие легаси-кода связано не столько с его возрастом, сколько с характеристиками, которые делают работу над ним сложной и непродуктивной, например:
- Отсутствие автоматизированных тестов. Когда разработчики вносят изменения в этот код, им приходится тестировать его вручную, поскольку не существует автоматического покрытия ни на каком уровне (модульные тесты, интеграционные тесты, сквозные тесты и т. д.).
- Отсутствие документации. Когда разработчикам приходится работать с этим кодом, им сложно его понять. Это может быть связано с тем, что код написан так, что его функциональность становится нечёткой, но на это также влияет отсутствие документации. Это может быть не буквальная документация, а просто контекст того, как он появился: проектный документ с чёткой мотивацией, почему эта функция существует, и стратегией того, как она будет реализована.
- Отсутствие эксперта. Когда команда вносит изменения в код, есть ли человек, который сможет его проверить? Это часто можно заметить по обзорам кода, которые выглядят как быстрое «вроде правильно», потому что рецензенту не хватает контекста и знаний для проведения тщательного анализа. Наиболее вероятный сценарий: рассматриваемый код был написан кем-то, кто покинул команду, и никто больше не работал над этой частью кодовой базы.

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

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

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

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

Источник:
https://leaddev.com/legacy-technical-debt-migrations/five-steps-managing-legacy-code
👍13
День 1836. #ЗаметкиНаПолях
Пять Шагов по Управлению Легаси-Кодом. Окончание

Начало

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

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

5. Чёткое определение масштаба переписывания
Иногда проект может выйти за рамки поэтапного переписывания и потребовать более агрессивного подхода. При этом важно работать над снижением риска, т.е. жёстко контролировать объём переписывания. Иногда можно переписать всю кодовую базу частями, например, переписать уровень данных, а затем переписывать интерфейс, вместо того чтобы заниматься обеими задачами одновременно. Учитывая, что переписывание обычно требует приостановки каких-либо работ или изменений в оригинале, лучше сводить количество переписываний и их объём к минимуму.

Кроме того, большое переписывание, занимающее недели или месяцы, — это рискованный релиз: в рабочую среду одновременно выбрасывается множество изменений. Вместо этого лучше вносить изменения постепенно, например, скрыв изменения «флагом функции». Так код поставляется, но не выполняется приложением, пока не будет установлен флаг. Затем вы можете включить этот флаг для определённой группы пользователей — например, для внутреннего персонала — и убедиться, что всё работает. Если есть какие-либо проблемы, можно быстро отключить новый код, выключив флаг. Это позволяет оперативно реагировать на неожиданные проблемы (проблемы всегда будут, независимо от того, насколько вы осторожны и старательны). Как только перезапись будет завершена, и вы уверены, что она прошла успешно, можете удалить флаг функции и весь старый код.

Итого
Легаси-код явно никуда не денется. Продукты меняются, команды развиваются, а технологии совершенствуются. Часть кода, который вы пишете сегодня, в ближайшие годы станет устаревшим — и не по вашей вине! Ключевым моментом является умение использовать устаревший код и рассматривать его как интересную техническую задачу. Со временем, работая над этими проблемами, вы накопите массу опыта и инструментов для работы с устаревшим кодом. Вы сможете постепенно модернизировать его с минимальными неудобствами для своих пользователей и коллег, увеличивая охват тестирования, удовлетворённость разработчиков и качество кода. Нет ничего более приятного, чем пул-реквест, который удаляет остатки кода, над переписыванием которого вы работали несколько месяцев.

Источник: https://leaddev.com/legacy-technical-debt-migrations/five-steps-managing-legacy-code
👍14
День 1837. #Шпаргалка
Примеры Кода для Повседневных Задач
В этой серии представлю вам коллекцию фрагментов кода C#, охватывающих широкий спектр сценариев, с которыми вы можете столкнуться при разработке ПО.

I. Словари
Словари - гибкая структура данных для соединения пар элементов.

1. Объединение двух словарей
Обычная операция при работе со структурами данных. Объединение словарей может оказаться непростой задачей, особенно при наличии повторяющихся ключей. Что делать при этом, будет зависеть от ваших потребностей. Вот несколько примеров:
var dict1 = new Dictionary<string, string> { 
{ "Superman", "Flight" }
};
var dict2 = new Dictionary<string, string> {
{ "Batman", "Gadgets" }
};

// LINQ
var merged = dict1
.Concat(dict2)
.ToDictionary(x => x.Key, x => x.Value);

// Цикл foreach
foreach (var item in dict2)
dict1[item.Key] = item.Value;

// Метод расширения Union
var merged2 = dict1
.Union(dict2)
.ToDictionary(x => x.Key, x => x.Value);


2. Инвертирование
Что, если вам нужно поменять местами ключи и значения словаря? Операция может осложниться, если у вас неуникальные или нехешируемые значения:
var heroes = new Dictionary<string, string>
{
{ "Flash", "Super Speed" },
{ "Green Lantern", "Power Ring" },
{ "Aquaman", "Atlantean Strength" }
};

// LINQ
var inverted = heroes
.ToDictionary(x => x.Value, x => x.Key);

// Цикл foreach
var inverted2 = new Dictionary<string, string>();
foreach (var item in heroes)
inverted2[item.Value] = item.Key;


3. Обратный поиск
Обратный поиск (найти ключ для данного значения) может быть полезен, когда словарь слишком велик для инвертирования:
var dimensions = new Dictionary<string, int>
{
{ "length", 10 },
{ "width", 20 },
{ "height", 30 }
};

int val = 20;

// "В лоб" – первый ключ
foreach (var d in dimensions)
{
if (d.Value == val)
{
Console.WriteLine($"{d.Key}: {d.Value}");
break;
}
}

// "В лоб" – все ключи
foreach (var d in dimensions)
{
if (d.Value == val)
Console.WriteLine($"{d.Key}: {d.Value}");
}

// LINQ – первый ключ
var key = dimensions
.FirstOrDefault(x => x.Value == val)
.Key;

// LINQ – все ключи
var keys = dimensions
.Where(x => x.Value == val)
.Select(x => x.Key);

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

Источник: https://medium.com/bytehide/100-csharp-code-snippets-for-everyday-problems-e913c786dec9
👍17👎3