C# (C Sharp) programming
18.7K subscribers
757 photos
38 videos
8 files
675 links
По всем вопросам- @haarrp

C# - обучающий канал Senior C# разработчика.

@ai_machinelearning_big_data - Machine learning

@itchannels_telegram - 🔥лучшие ит-каналы

@csharp_ci - C# академия

@pythonlbooks- книги📚

Реестр РКН: https://clck.ru/3Fk3kb
Download Telegram
9 "Черная магия" и "трюки" в языке C#

C# является чрезвычайно продвинутым языком благодаря наличию в нем "синтаксического сахара".

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

Итак, давайте посмотрим, являются ли эти возможности в C# жестко прописанными компилятором ("черная магия") или расширяемыми ("трюки") "утиной типизацией".

Попробуйте определить сами)

Правильные ответы вы найдете в статье.

1. LINQ operations, with IEnumerable<T> type

2. async/await, with Task/ValueTask types

3. Expression trees, with Expression<T> type

4. Interpolated strings, with FormattableString type

5. yield return, with IEnumerable<T> type;

6. foreach loop, с IEnumerable<T> type

7. using keyword, with IDisposable interface

8. T?, with Nullable<T> type

9. Generic operations of Index/Range for any type


📌Статья

@csharp_ci
🖥 100 скриптов на C# для решения повседневных задач

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

Эти фрагменты не только демонстрируют возможности C#, но и служат полезным ресурсом для расширения вашего инструментария программиста.

Так что, независимо от того, являетесь ли вы опытным разработчиком или новичком в C#, погрузитесь в работу и изучите эти изящные решения с кодом!

📌Статья

@csharp_ci
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥Awesome-C# огромный список полезных фреймворков, готовых скриптов, библиотек и программного обеспечения.

Github

@csharp_ci
JsonProperty.EFCore: Упрощаем работу с JSON-полями в Entity Framework Core

Иногда перед разработчиками встает задача использования JSON-полей в Entity Framework Core. Традиционный подход с использованием Fluent API требует написания дополнительного кода, что может усложнить проект. Пакет JsonProperty.EFCore решает эту проблему.

Проблема: Сложное управление JSON-полями
Entity Framework Core
отлично поддерживает работу с реляционными базами данных, но управление JSON-полями может стать непростой задачей.

JsonProperty.EFCore: Упрощенный подход
JsonProperty.EFCore предлагает новое решение для управления JSON-полями. Он позволяет использовать JSON-поля в EF Core без необходимости настройки сложного Fluent API. Благодаря этому открытому проекту NuGet, разработчики могут упростить свой рабочий процесс и сосредоточиться на создании логики приложения, минуя сложные настройки EF Core.

Особенности и преимущества
Простая интеграция:
JsonProperty.EFCore предлагает простой процесс интеграции.

Поддержка обобщенных типов: Пакет поддерживает обобщенные типы, такие как JsonEnumerable<T> и JsonDictionary<TKey, TValue>, что позволяет разработчикам работать с пользовательскими типами элементов в коллекциях JSON без усилий.

Безупречное управление JSON: С JsonProperty.EFCore управление JSON-полями становится намного проще.
Строгая сериализация типов: Пакет позволяет разработчикам включить строгую сериализацию типов.

Полиморфизм: строгая типизация позволяет сохранить полиморфные типы при сериализации и десериализации в JSON.

Примеры использования:
JsonProperty.EFCore, чтобы продемонстрировать его полезность и удобство:

Хранение параметров продукта:

public class Product
{
public int Id { get; set; }
public string Name { get; set; }
public JsonDictionary Parameters { get; set; } = new();
}
Запись JsonDictionary
аналогична JsonDictionary<string, object>. При этом полиморфизм позволяет хранить значения любых типов в таком словаре.

А вот пример управления коллекцией JsonDictionary:


Product product = new() {Name="Phone",Price=500.95m,Amount=21,Parameters={
VirtualDictionary = new Dictionary<string,object>() {
{"Camera",13.5 },{"OS","Android" },{"Screen","1080x900"},{"Storage",32}
}
}};
db.Goods.Add(product);
db.SaveChanges();

Это сгенерирует следующие данные для поля в формате JSON, если настройка JsonSettings.StrictTypeSerialization имеет значение true (по умолчанию):

{
"Camera": [13.5, "System.Double"],
"OS": ["Android", "System.String"],
"Screen": ["1080x900", "System.String"],
"Storage": [32, "System.Int32"]
}

Также можно добавлять и редактировать элементы поля JsonDictionary:

Product product = db.Goods.FirstOrDefault();
product.Parameters.Add("Battery capacity", 3000);
product.Parameters.Edit(dict => {
dict["Battery capacity"] = 4000;
dict["Storage"] = 64;
dict.Add("RAM", 4);
return dict;
});

После этого JSON-поле примет следующий вид:

{
"Camera": [13.5, "System.Double"],
"OS": ["Android", "System.String"],
"Screen": ["1080x900", "System.String"],
"Storage": [64, "System.Int32"],
"Battery capacity": [4000, "System.Int32"],
"RAM": [4, "System.Int32"]
}

Управление элементами списка дел:


public class Note
{
public int Id { get; set; }
public string Header { get; set; }
public JsonList<TodoItem> Todos { get; set; } = new();
}

При этом в списке JsonList<TodoItem> можно также хранить элементы с типом, наследуемым от TodoItem.

Простое добавление полиморфного поля:

JsonProperty.EFCore:

using JsonProperty.EFCore;

class MyEntity
{
public int Id { get; set; }
public int Title { get; set; }
public JsonItem<Base> Content { get; set; } = new();
}

Теперь можно использовать полиморфное поле:

MyEntity myEntity = new();
myEntity.Content.Serialize(new DerivedType1());
Base val = myEntity.Content.Deserialize();
Console.WriteLine(val is DerivedType1); //true

Github

@csharp_ci
🔥C# Source Generators

Полезный список Source Generators (генераторов кода) C#.

Какие задачи решают генераторы?

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

Было бы неплохо отдать эту задачу генератору, который напишет этот код за нас. В том числе можно, например, добавить всем типам в проекте осмысленный метод ToString, создавать типы по схеме, добавить mapping, например, как в AutoMapper, материализацию объектов баз данных.


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


Github
Source Generators в действии

@csharp_ci
🎨 Awesome Software Architecture

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

https://awesome-architecture.com/

@csharp_ci
🎉 .NET 8 Preview 7 уже доступен 🎉

Здесь собраны все ссылки и ресурсы, необходимые для работы с этой последней версией.

https://devblogs.microsoft.com/dotnet/announcing-dotnet-8-preview-7/

@csharp_ci
🖥 Ленивая инициализация в C#

Отложенная инициализация или «ленивая» инициализация — это способ доступа к объекту, скрывающий за собой механизм, позволяющий отложить создание этого объекта до момента первого обращения. Необходимость ленивой инициализации может возникнуть по разным причинам: начиная от желания снизить нагрузку при старте приложения и заканчивая оптимизацией редко используемого функционала. И действительно, не все функции приложения используются всегда и, тем более, сразу, потому создание объектов, реализующих их, вполне рационально отложить до лучших времён. Я хотел бы рассмотреть варианты ленивой инициализации, доступные в языке 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
Что выведет код ?

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#

Модульность и возможность повторного использования
Модульность и возможность повторного использования являются ключевыми преимуществами функционального программирования, и 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