🔥C# Source Generators
Полезный список Source Generators (генераторов кода) C#.
Какие задачи решают генераторы?
В первую очередь — создание шаблонного кода. Если у вас, например, есть методы Equals, GetHashCode, операторы равенства и неравенства, скажем, обеспечивающие структурное сравнение данных, писать их вручную для каждого типа очень неудобно.
Было бы неплохо отдать эту задачу генератору, который напишет этот код за нас. В том числе можно, например, добавить всем типам в проекте осмысленный метод ToString, создавать типы по схеме, добавить mapping, например, как в AutoMapper, материализацию объектов баз данных.
Во вторых, благодаря тому, что мы теперь легко и просто можем создавать шаблонный код, открываются некоторые интересные возможности по оптимизации наших приложений. Например там, где мы раньше использовали рефлексию просто для того, чтобы не писать руками код. Скажем, регистрация типов для dependency injection, методы сериализации.
▪Github
▪Source Generators в действии
@csharp_ci
Полезный список Source Generators (генераторов кода) C#.
Какие задачи решают генераторы?
В первую очередь — создание шаблонного кода. Если у вас, например, есть методы Equals, GetHashCode, операторы равенства и неравенства, скажем, обеспечивающие структурное сравнение данных, писать их вручную для каждого типа очень неудобно.
Было бы неплохо отдать эту задачу генератору, который напишет этот код за нас. В том числе можно, например, добавить всем типам в проекте осмысленный метод ToString, создавать типы по схеме, добавить mapping, например, как в AutoMapper, материализацию объектов баз данных.
Во вторых, благодаря тому, что мы теперь легко и просто можем создавать шаблонный код, открываются некоторые интересные возможности по оптимизации наших приложений. Например там, где мы раньше использовали рефлексию просто для того, чтобы не писать руками код. Скажем, регистрация типов для dependency injection, методы сериализации.
▪Github
▪Source Generators в действии
@csharp_ci
🎨 Awesome Software Architecture
Полезный список статей и ресурсов для изучения и применения на практике архитектуры, паттернов и принципов программного обеспечения.
https://awesome-architecture.com/
@csharp_ci
Полезный список статей и ресурсов для изучения и применения на практике архитектуры, паттернов и принципов программного обеспечения.
https://awesome-architecture.com/
@csharp_ci
🎉 .NET 8 Preview 7 уже доступен 🎉
Здесь собраны все ссылки и ресурсы, необходимые для работы с этой последней версией.
https://devblogs.microsoft.com/dotnet/announcing-dotnet-8-preview-7/
@csharp_ci
Здесь собраны все ссылки и ресурсы, необходимые для работы с этой последней версией.
https://devblogs.microsoft.com/dotnet/announcing-dotnet-8-preview-7/
@csharp_ci
🟡 Дайджест полезных материалов из мира C# за неделю
Почитать:
— ChatGPT в написании юнит тестов
— Обзор подозрительных мест в исходном коде MassTransit
— Fancy Widgets — виджеты рабочего стола на AvaloniaUI
— Базы Данных + Telegram Бот на C#. SKitLs Framework v.2
— Список популярных утечек с GitHub: Анализ репозиториев компаний
— JsonProperty.EFCore: Упрощаем работу с JSON-полями в Entity Framework Core
— Всегда ли в C# есть упаковка при конкатенации со строкой и интерполяции?
— Globally Exception Handling using Exception Filters vs Middleware
— Converting ASP.NET Core user secrets to environment variables at runtime
— Automatizando geração de logs com Delegating Handler em .NET
— Game Dev Digest — Issue #199 - Inspiration Issue
— .NET 8 Web API - Write Endpoints
— .NET 8Web API - Custom Request
— .NET Web API - PredicateBuilder
— .NET 8 Web API - Read End Points
— Combining Blazor WebAssembly and .Net MVC application - part 1
— Comment ajouter des filigranes d'image aux fichiers PDF avec C# et VB.NET
Посмотреть:
🌐Languages & Runtime Community Standup - Catching up on F#
Хорошего дня!
@csharp_ci
Почитать:
— ChatGPT в написании юнит тестов
— Обзор подозрительных мест в исходном коде MassTransit
— Fancy Widgets — виджеты рабочего стола на AvaloniaUI
— Базы Данных + Telegram Бот на C#. SKitLs Framework v.2
— Список популярных утечек с GitHub: Анализ репозиториев компаний
— JsonProperty.EFCore: Упрощаем работу с JSON-полями в Entity Framework Core
— Всегда ли в C# есть упаковка при конкатенации со строкой и интерполяции?
— Globally Exception Handling using Exception Filters vs Middleware
— Converting ASP.NET Core user secrets to environment variables at runtime
— Automatizando geração de logs com Delegating Handler em .NET
— Game Dev Digest — Issue #199 - Inspiration Issue
— .NET 8 Web API - Write Endpoints
— .NET 8Web API - Custom Request
— .NET Web API - PredicateBuilder
— .NET 8 Web API - Read End Points
— Combining Blazor WebAssembly and .Net MVC application - part 1
— Comment ajouter des filigranes d'image aux fichiers PDF avec C# et VB.NET
Посмотреть:
🌐Languages & Runtime Community Standup - Catching up on F#
Хорошего дня!
@csharp_ci
Отложенная инициализация или «ленивая» инициализация — это способ доступа к объекту, скрывающий за собой механизм, позволяющий отложить создание этого объекта до момента первого обращения. Необходимость ленивой инициализации может возникнуть по разным причинам: начиная от желания снизить нагрузку при старте приложения и заканчивая оптимизацией редко используемого функционала. И действительно, не все функции приложения используются всегда и, тем более, сразу, потому создание объектов, реализующих их, вполне рационально отложить до лучших времён. Я хотел бы рассмотреть варианты ленивой инициализации, доступные в языке C#.
Для демонстрации примеров я буду использовать класс Test, у которого есть свойство BlobData, возвращающее объект типа Blob, который по легенде создаётся довольно медленно, и было решено создавать его лениво.
class Test
{
public Blob BlobData
{
get
{
return new Blob();
}
}
}
Проверка на null
Самый простой вариант, доступный с первых версий языка, — это создание неинициализированной переменной и проверка её на null перед возвращением. Если переменная равна null, создаём объект и присваиваем этой переменной, а потом его возвращаем. При повторном обращении объект уже будет создан и мы сразу его вернём.
class Test
{
private Blob _blob = null;
public Blob BlobData
{
get
{
if (_blob == null)
{
_blob = new Blob();
}
return _blob;
}
}
}
Объект типа Blob тут создаётся при первом обращении к свойству. Либо не создаётся, если он по какой-то причине в этой сессии программе не понадобился.
Тернарный оператор ?:
В C# есть тернарный оператор, позволяющий проверить условие и, если оно истинно вернуть одно значение, а если ложно, — другое. Мы можем использовать его для того, чтобы немного сократить и упростить код.
class Test
{
private Blob _blob = null;
public Blob BlobData
{
get
{
return _blob == null
? _blob = new Blob()
: _blob;
}
}
}
Суть осталась той же. Если объект не инициализирован, инициализируем и возвращаем. Ежели уже инициализирован, то просто сразу возвращаем.
is null
Ситуации бывают разные и мы, например, можем столкнуться с такой, в которой у класса Blob перегружен оператор ==. Для этого, вероятно, нам может потребоваться сделать проверку is null вместо == null. Доступно в свежих версиях языка.
return _blob is null
? _blob = new Blob()
: _blob;
Но это так, небольшое отступление.
Null-coalescing оператор ??
Ещё больше упростить код нам поможет бинарный оператор ??
Суть его работы такова. Если первый операнд не равен null, то он и возвращается. Если же первый операнд равен null, возвращается второй.
class Test
{
private Blob _blob = null;
public Blob BlobData
{
get
{
return _blob ?? (_blob = new Blob());
}
}
}
Второй операнд пришлось взять в круглые скобки из-за приоритета операций.
📌Статья
@csharp_ci
Please open Telegram to view this post
VIEW IN TELEGRAM
Что выведет код ?
Пишите ответ в комментариях👇
@csharp_ci
B obj1 = new B();
A obj2 = new B();
obj1.Foo(123);
obj1.Foo("123");
obj2.Foo(123);
obj2.Foo("123");
Console.ReadKey();
class A
{
public void Foo(dynamic arg)
{
Console.WriteLine("dynamic");
}
public void Foo(string arg)
{
Console.WriteLine("string");
}
}
class B : A
{
public void Foo(int arg)
{
Console.WriteLine("int");
}
public void Foo(object arg)
{
Console.WriteLine("object");
}
}
Пишите ответ в комментариях👇
@csharp_ci
⚡Заметки С# разработчика
Канал для тех, кто интересуется C#, ASP.NET архитектурой программного обеспечения, оптимизацией производительности систем, масштабируемостью, надежностью и другими аспектами разработки программного обеспечения.
Канал подойдет тем, кто хочет улучшить свои навыки и знания в C#.
📌 Лучшие практики кода
📌 System Design
📌 Чистая Архитектура
📌 Проектирование
Стоит подписаться: @csharp_1001_notes
Канал для тех, кто интересуется C#, ASP.NET архитектурой программного обеспечения, оптимизацией производительности систем, масштабируемостью, надежностью и другими аспектами разработки программного обеспечения.
Канал подойдет тем, кто хочет улучшить свои навыки и знания в C#.
📌 Лучшие практики кода
📌 System Design
📌 Чистая Архитектура
📌 Проектирование
Стоит подписаться: @csharp_1001_notes
Модульность и возможность повторного использования
Модульность и возможность повторного использования являются ключевыми преимуществами функционального программирования, и C# предоставляет ряд возможностей, позволяющих легко достичь этих целей. Рассмотрим пример на C#, демонстрирующий достоинства модульности и многократного использования функционального программирования:
using System;
using System.Collections.Generic;
using System.Linq;
namespace ModularityAndReusabilityExample
{
class Program
{
static void Main(string[] args)
{
List<int> numbers = new List<int> { 1, 2, 3, 4, 5 };
int sum = numbers.Sum();
int product = numbers.Product();
Console.WriteLine("Sum: " + sum);
Console.WriteLine("Product: " + product);
}
}
public static class Extensions
{
public static int Product(this IEnumerable<int> source)
{
return source.Aggregate(1, (acc, x) => acc * x);
}
}
}
В этом примере мы создали список чисел и использовали два метода расширения для вычисления суммы и произведения этих чисел. Метод Sum — это встроенный метод, предоставляемый C#, а метод Product — это пользовательский метод расширения, который мы определили сами.
Инкапсулировав логику вычисления произведения списка чисел в отдельный метод, мы создали высокомодульный и многократно используемый фрагмент кода. Этот метод расширения можно повторно использовать в различных приложениях и при необходимости легко модифицировать или расширять.
Кроме того, использование методов расширения позволяет писать более выразительный и читабельный код. Вместо того чтобы писать цикл для вычисления произведения чисел, мы можем просто вызвать метод расширения Product для списка чисел. Это делает код более простым, лаконичным и удобным для чтения.
В целом преимущества функционального программирования, связанные с модульностью и возможностью повторного использования, позволяют создавать хорошо поддерживаемый и масштабируемый код. Разбивая сложные задачи на более мелкие, независимые функции, мы можем создать библиотеку композитных функций, которые можно повторно использовать в различных приложениях.
Используя возможности C# и функционального программирования, разработчики могут создавать надежные и масштабируемые программные системы, рассчитанные на длительную эксплуатацию.
📌 Читать дальше
@csharp_ci
Please open Telegram to view this post
VIEW IN TELEGRAM
⚡Легкий способ получать свежие обновлении и следить за трендами в разработке на вашем языке. Находите свой стек и подписывайтесь:
Машинное обучение: @ai_machinelearning_big_data
Go: @Golang_google
C#: @csharp_1001_notes
Базы данных: @sqlhub
Python: @pythonl
C/C++/: @cpluspluc
Data Science: @data_analysis_ml
Devops: @devOPSitsec
Rust: @rust_code
Javascript: @javascriptv
React: @react_tg
PHP: @phpshka
Docker: @docker
Android: @android_its
Мобильная разработка: @mobdevelop
Linux: linuxacademy
Big Data: t.iss.one/bigdatai
Хакинг: @linuxkalii
Java:@javatg
Собеседования: @machinelearning_interview
💼 Папка с вакансиями: t.iss.one/addlist/_zyy_jQ_QUsyM2Vi
Папка Go разработчика: t.iss.one/addlist/MUtJEeJSxeY2YTFi
Папка Python разработчика: t.iss.one/addlist/eEPya-HF6mkxMGIy
🔥ИТ-Мемы: t.iss.one/memes_prog
🇬🇧Английский: @english_forprogrammers
Машинное обучение: @ai_machinelearning_big_data
Go: @Golang_google
C#: @csharp_1001_notes
Базы данных: @sqlhub
Python: @pythonl
C/C++/: @cpluspluc
Data Science: @data_analysis_ml
Devops: @devOPSitsec
Rust: @rust_code
Javascript: @javascriptv
React: @react_tg
PHP: @phpshka
Docker: @docker
Android: @android_its
Мобильная разработка: @mobdevelop
Linux: linuxacademy
Big Data: t.iss.one/bigdatai
Хакинг: @linuxkalii
Java:@javatg
Собеседования: @machinelearning_interview
💼 Папка с вакансиями: t.iss.one/addlist/_zyy_jQ_QUsyM2Vi
Папка Go разработчика: t.iss.one/addlist/MUtJEeJSxeY2YTFi
Папка Python разработчика: t.iss.one/addlist/eEPya-HF6mkxMGIy
🔥ИТ-Мемы: t.iss.one/memes_prog
🇬🇧Английский: @english_forprogrammers
Media is too big
VIEW IN TELEGRAM
Наглядный по работе docker-compose.
📌 Источник
@csharp_ci
Please open Telegram to view this post
VIEW IN TELEGRAM
✔ Redis Explained
Глубокое техническое погружение во все тонкости Redis.
В статье рассматриваются различные топологии Redis, персистентность данных и форкинг процессов.
Отличная иллюстрированная статья для глубокого понимания Redis.
▪Читать
@csharp_ci
Глубокое техническое погружение во все тонкости Redis.
В статье рассматриваются различные топологии Redis, персистентность данных и форкинг процессов.
Отличная иллюстрированная статья для глубокого понимания Redis.
▪Читать
@csharp_ci
🟡 Дайджест полезных материалов из мира :C# за неделю
Почитать:
— UI Router в Unity + CustomEditor
— Преимущества функционального программирования на примерах C#
— Объяснения по шардинга баз данных
— Реализация обмена сообщениями через MassTransit
— Конкурентная очередь с приоритетами (неудачно)
— Бессильный сборщик мусора или неуправляемая память в .NET
— Unity: Как реализовать бесконечный ListView с изображениями?
— ChatGPT в написании юнит тестов
— Robust use of HTTP Client
— How to deploy a BLAZOR WASM Web Application to GitHub Page
— Intelligent Queries By Entity Intelligence
— Boost your productivity in Visual Studio - Shortcuts
— Dealing with C# & GitHub Copilot in Visual Studio 2022
— Working with C# in VS Code.
— Game Dev Digest — Issue #200 - Develop Faster
— Time Period Library for .NET
— Wie man in C#/VB.NET die Hintergrundfarbe und das Hintergrundbild von PDF-Dokumenten festlegt
— [C#/VB.NET] Hintergrundfarbe von Absätzen und Text in Word-Dokumenten festlegen
Посмотреть:
🌐On .NET Live - Building web apps with Blazor and Spark.NET
🌐 Сравнение Unity и Unreal Engine: Что выбрать новичку?
Хорошего дня!
@csharp_ci
Почитать:
— UI Router в Unity + CustomEditor
— Преимущества функционального программирования на примерах C#
— Объяснения по шардинга баз данных
— Реализация обмена сообщениями через MassTransit
— Конкурентная очередь с приоритетами (неудачно)
— Бессильный сборщик мусора или неуправляемая память в .NET
— Unity: Как реализовать бесконечный ListView с изображениями?
— ChatGPT в написании юнит тестов
— Robust use of HTTP Client
— How to deploy a BLAZOR WASM Web Application to GitHub Page
— Intelligent Queries By Entity Intelligence
— Boost your productivity in Visual Studio - Shortcuts
— Dealing with C# & GitHub Copilot in Visual Studio 2022
— Working with C# in VS Code.
— Game Dev Digest — Issue #200 - Develop Faster
— Time Period Library for .NET
— Wie man in C#/VB.NET die Hintergrundfarbe und das Hintergrundbild von PDF-Dokumenten festlegt
— [C#/VB.NET] Hintergrundfarbe von Absätzen und Text in Word-Dokumenten festlegen
Посмотреть:
🌐On .NET Live - Building web apps with Blazor and Spark.NET
🌐 Сравнение Unity и Unreal Engine: Что выбрать новичку?
Хорошего дня!
@csharp_ci
✔Сapa
capa - полезный инструмент с открытым исходным кодом для определения возможностей в исполняемых файлах.
Вы запускаете ее для PE, ELF, .NET файла или шелл-кода, и он говорит вам, что, по его мнению, может сделать программа.
Например, можно предположить, что файл является бэкдором, способен устанавливать службы или использует HTTP для запросов.
▪Github
▪Установка
@csharp_ci
capa - полезный инструмент с открытым исходным кодом для определения возможностей в исполняемых файлах.
Вы запускаете ее для PE, ELF, .NET файла или шелл-кода, и он говорит вам, что, по его мнению, может сделать программа.
Например, можно предположить, что файл является бэкдором, способен устанавливать службы или использует HTTP для запросов.
▪Github
▪Установка
@csharp_ci
⚡Продвинутые случи использования ограничении частоты запросов в .NET
• Вот как определить ограничения, вызвав метод AddTokenBucketLimiter (картинка 1)
• Ограничение пользователей по IP-адресам (картинка 2)
• Ограничение с учетом прокси.(картинка 3)
• Ограничение пользователей по идентификационным признакам (картинка 4)
• Реализация ограничение на обратном прокси с помощью YARP, необходимо картинка 5)
📌 Читать статью
@csharp_ci
• Вот как определить ограничения, вызвав метод AddTokenBucketLimiter (картинка 1)
• Ограничение пользователей по IP-адресам (картинка 2)
• Ограничение с учетом прокси.(картинка 3)
• Ограничение пользователей по идентификационным признакам (картинка 4)
• Реализация ограничение на обратном прокси с помощью YARP, необходимо картинка 5)
📌 Читать статью
@csharp_ci
🚀Паттерн проектирования Singleton в C#: Полное руководство
Singleton - порождающий шаблон проектирования, гарантирующий, что в однопоточном приложении будет единственный экземпляр некоторого класса, и предоставляющий глобальную точку доступа к этому экземпляру.
Когда надо использовать Синглтон? Когда необходимо, чтобы для класса существовал только один экземпляр
Синглтон позволяет создать объект только при его необходимости. Если объект не нужен, то он не будет создан. В этом отличие синглтона от глобальных переменных.
Классическая реализация данного шаблона проектирования на C# выглядит следующим образом:
В классе определяется статическая переменная - ссылка на конкретный экземпляр данного объекта и приватный конструктор. В статическом методе getInstance() этот конструктор вызывается для создания объекта, если, конечно, объект отсутствует и равен null.
Для применения паттерна Одиночка создадим небольшую программу. Например, на каждом компьютере можно одномоментно запустить только одну операционную систему. В этом плане операционная система будет реализоваться через паттерн синглтон:
Синглтон и многопоточность
При применении паттерна синглтон в многопоточным программах мы можем столкнуться с проблемой, которую можно описать следующим образом:
Здесь запускается дополнительный поток, который получает доступ к синглтону. Параллельно выполняется тот код, который идет запуска потока и кторый также обращается к синглтону. Таким образом, и главный, и дополнительный поток пытаются инициализровать синглтон нужным значением - "Windows 10", либо "Windows 8.1". Какое значение сиглтон получит в итоге, пресказать в данном случае невозможно.
Вывод программы может быть такой:
В итоге мы сталкиваемся с проблемой инициализации синглтона, когда оба потока одновременно обращаются к коду:
Чтобы решить эту проблему, перепишем класс синглтона следующим образом:
Чтобы избежать одновременного доступа к коду из разных потоков критическая секция заключается в блок lock.
📌 Статья
@csharp_ci
Singleton - порождающий шаблон проектирования, гарантирующий, что в однопоточном приложении будет единственный экземпляр некоторого класса, и предоставляющий глобальную точку доступа к этому экземпляру.
Когда надо использовать Синглтон? Когда необходимо, чтобы для класса существовал только один экземпляр
Синглтон позволяет создать объект только при его необходимости. Если объект не нужен, то он не будет создан. В этом отличие синглтона от глобальных переменных.
Классическая реализация данного шаблона проектирования на C# выглядит следующим образом:
class Singleton
{
private static Singleton instance;
private Singleton()
{}
public static Singleton getInstance()
{
if (instance == null)
instance = new Singleton();
return instance;
}
}
В классе определяется статическая переменная - ссылка на конкретный экземпляр данного объекта и приватный конструктор. В статическом методе getInstance() этот конструктор вызывается для создания объекта, если, конечно, объект отсутствует и равен null.
Для применения паттерна Одиночка создадим небольшую программу. Например, на каждом компьютере можно одномоментно запустить только одну операционную систему. В этом плане операционная система будет реализоваться через паттерн синглтон:
class Program
{
static void Main(string[] args)
{
Computer comp = new Computer();
comp.Launch("Windows 8.1");
Console.WriteLine(comp.OS.Name);
// у нас не получится изменить ОС, так как объект уже создан
comp.OS = OS.getInstance("Windows 10");
Console.WriteLine(comp.OS.Name);
Console.ReadLine();
}
}
class Computer
{
public OS OS { get; set; }
public void Launch(string osName)
{
OS = OS.getInstance(osName);
}
}
class OS
{
private static OS instance;
public string Name { get; private set; }
protected OS(string name)
{
this.Name=name;
}
public static OS getInstance(string name)
{
if (instance == null)
instance = new OS(name);
return instance;
}
}
Синглтон и многопоточность
При применении паттерна синглтон в многопоточным программах мы можем столкнуться с проблемой, которую можно описать следующим образом:
static void Main(string[] args)
{
(new Thread(() =>
{
Computer comp2 = new Computer();
comp2.OS = OS.getInstance("Windows 10");
Console.WriteLine(comp2.OS.Name);
})).Start();
Computer comp = new Computer();
comp.Launch("Windows 8.1");
Console.WriteLine(comp.OS.Name);
Console.ReadLine();
}
Здесь запускается дополнительный поток, который получает доступ к синглтону. Параллельно выполняется тот код, который идет запуска потока и кторый также обращается к синглтону. Таким образом, и главный, и дополнительный поток пытаются инициализровать синглтон нужным значением - "Windows 10", либо "Windows 8.1". Какое значение сиглтон получит в итоге, пресказать в данном случае невозможно.
Вывод программы может быть такой:
Windows 8.1
Windows 10
Или такой:
Windows 8.1
Windows 8.1
В итоге мы сталкиваемся с проблемой инициализации синглтона, когда оба потока одновременно обращаются к коду:
if (instance == null)
instance = new OS(name);
Чтобы решить эту проблему, перепишем класс синглтона следующим образом:
class OS
{
private static OS instance;
public string Name { get; private set; }
private static object syncRoot = new Object();
protected OS(string name)
{
this.Name = name;
}
public static OS getInstance(string name)
{
if (instance == null)
{
lock (syncRoot)
{
if (instance == null)
instance = new OS(name);
}
}
return instance;
}
}
Чтобы избежать одновременного доступа к коду из разных потоков критическая секция заключается в блок lock.
📌 Статья
@csharp_ci
Очень интересный проект, который показывает элегантность и выразительность F# – формальная (и исполняемая) спецификация для RISC-V ISA, написанная в функциональном стиле.
Авторы демонстрируют «чрезвычайно элементарную» реализацию F#, чтобы сделать ее читаемой и пригодной для широкой аудитории.
▪Github
▪ISA инструкции
@csharp_ci
Please open Telegram to view this post
VIEW IN TELEGRAM