Введение
C# — это высокоуровневый, объектно-ориентированный язык программирования, разработанный Microsoft. В 2025 году он остается одним из самых популярных языков благодаря своей универсальности, производительности и постоянному развитию. C# используется в различных областях, включая веб-разработку (ASP.NET Core), создание игр (Unity), мобильные приложения (Xamarin), десктопные приложения (WPF, MAUI) и облачные решения (Azure). В этой статье мы рассмотрим ключевые концепции, новые возможности и лучшие практики современного C#.
1. Современный синтаксис и функциональные возможности
1.1. Типы record и init-only свойства
Типы record
появились в C# 9.0 и предназначены для создания неизменяемых (immutable) объектов с автоматической реализацией Equals
, GetHashCode
и ToString
. Они идеально подходят для DTO (Data Transfer Objects) и моделей данных.
public record Person(string FirstName, string LastName, int Age);
var person1 = new Person(«John», «Doe», 30);
var person2 = person1 with { Age = 31 };
Свойства init
позволяют устанавливать значения только при инициализации:
public class Product
{
public string Name { get; init; }
public decimal Price { get; init; }
}
var product = new Product { Name = «Laptop», Price = 999.99m };
1.2. Pattern Matching
Pattern matching упрощает проверку типов и структур данных:
object obj = «Hello, world!»;
if (obj is string message)
{
Console.WriteLine($»Длина строки: {message.Length}«);
}
var result = obj switch
{
int i => $»Целое число: {i}«,
string s => $»Строка: {s}«,
_ => «Неизвестный тип»
};
1.3. Лямбда-выражения и локальные функции
Лямбда-выражения делают код более лаконичным:
Func<int, int, int> add = (x, y) => x + y;
Console.WriteLine(add(5, 3));
Локальные функции полезны для инкапсуляции логики внутри методов:
public void ProcessData(List<int> data)
{
int CalculateAverage() => data.Sum() / data.Count;
Console.WriteLine($»Среднее: {CalculateAverage()}«);
}
2. Асинхронное программирование
2.1. async/await
Асинхронное программирование позволяет избегать блокировки потока при выполнении I/O-операций:
public async Task<string> DownloadDataAsync(string url)
{
using var client = new HttpClient();
return await client.GetStringAsync(url);
}
2.2. ValueTask
ValueTask
— это оптимизация для случаев, когда результат может быть доступен синхронно:
public ValueTask<int> GetValueAsync(bool fromCache)
{
return fromCache ? new ValueTask<int>(42) : new ValueTask<int>(LoadFromDbAsync());
}
private async Task<int> LoadFromDbAsync() => await Task.FromResult(100);
2.3. Параллельное выполнение задач
Task.WhenAll
и Task.WhenAny
позволяют эффективно управлять несколькими асинхронными операциями:
var task1 = DownloadDataAsync(«https://api.example.com/data1»);
var task2 = DownloadDataAsync(«https://api.example.com/data2»);
await Task.WhenAll(task1, task2);
3. Работа с данными и LINQ
3.1. LINQ (Language Integrated Query)
LINQ предоставляет мощные инструменты для работы с коллекциями:
var numbers = new List<int> { 1, 2, 3, 4, 5 };
var evenNumbers = numbers.Where(n => n % 2 == 0).ToList();
var squares = numbers.Select(n => n * n);
3.2. Иммутабельные коллекции
Иммутабельные коллекции (ImmutableList
, ImmutableDictionary
) полезны для многопоточных приложений:
using System.Collections.Immutable;
var immutableList = ImmutableList.Create(1, 2, 3);
var newList = immutableList.Add(4);
3.3. Span<T> и Memory<T>
Эти типы позволяют работать с памятью более эффективно, избегая лишних аллокаций:
int[] array = { 1, 2, 3, 4, 5 };
Span<int> span = array.AsSpan();
int sum = 0;
foreach (var num in span)
{
sum += num;
}
4. Обработка ошибок и безопасность
4.1. Исключения и фильтры
Фильтры исключений позволяют обрабатывать ошибки более гибко:
try
{
}
catch (HttpRequestException ex) when (ex.StatusCode == 404)
{
Console.WriteLine(«Ресурс не найден»);
}
4.2. Nullable Reference Types
Эта функция помогает избежать NullReferenceException
:
#nullable enable
string? nullableString = null;
string nonNullableString = «Hello»;
5. Лучшие практики
- Используйте Dependency Injection для управления зависимостями:
services.AddScoped<IMyService, MyService>();
- Пишите модульные тесты с помощью xUnit или NUnit:
[Fact]
public void Test_Addition()
{
Assert.Equal(4, 2 + 2);
}
- Оптимизируйте производительность с помощью
Span<T>
, ArrayPool
и MemoryCache
.
- Используйте Source Generators для автоматической генерации кода.
Заключение
Современный C# — это мощный инструмент для разработки высокопроизводительных и надежных приложений. Используя новые возможности языка, такие как record
, pattern matching, асинхронное программирование и LINQ, вы сможете писать чистый и эффективный код. Для углубленного изучения рекомендуется ознакомиться с документацией Microsoft, книгами по C# и участием в open-source проектах.Для дальнейшего изучения рекомендуем:
- Современные стандарты C# и .NET (C# 12, .NET 8/9)
- Принципы Domain-Driven Design (DDD) для сложных бизнес-приложений
- Методы профилирования и оптимизации (Benchmark.NET, dotTrace, PerfView)
- Работу с распределёнными системами (Microservices, Event Sourcing, CQRS)
- Продвинутые техники параллельного программирования (Channels, Actor Model, Dataflow)