Разбираем Однофайловые Приложения в .NET 10. Начало
C# всегда был немного перегружен церемониями. Даже простейший «Hello World» традиционно требовал файла решения, файла проекта и достаточного количества шаблонного кода, чтобы заставить вас задуматься, а не лучше ли использовать скриптовый язык. В .NET 10 представлены однофайловые приложения.
Что это?
Идея проста: пишете код C# в одном CS-файле и запускаете его напрямую. Не нужно настраивать структуру целого проекта для быстрого служебного скрипта.
Все прелести C# сохраняются: типобезопасность, производительность, богатая стандартная библиотека. Но теперь вы можете использовать его для тех одноразовых скриптов, для которых создание полноценного проекта было бы излишним. По-прежнему можно ссылаться на NuGet-пакеты, на другие проекты C#, использовать конкретные SDK и настраивать свойства проекта — всё это из одного файла с помощью специальных директив.
Функционал основан на операторах верхнего уровня и доводит их до логического завершения. Если уж мы позволяем пользователям пропускать церемонию создания класса и метода Main, почему бы не позволить им также пропускать церемонию создания проекта?
Начало работы
Предположим, нужно быстро проверить, на какой день недели приходится определённая дата. Создадим файл с date-checker.cs:
var targetDate = new DateTime(2025, 12, 31);
Console.WriteLine(
$"Новый год в 2025 - это {targetDate.DayOfWeek}");
Console.WriteLine(
$"Через {(targetDate - DateTime.Today).Days} дней");
Выполним это с помощью:
dotnet run date-checker.cs
При первом запуске CLI творит чудеса: создаёт виртуальный проект, компилирует код и кэширует всё. Последующие запуски выполняются практически мгновенно, поскольку CLI достаточно умён, чтобы определять, когда ничего не изменилось.
Пример из реальной жизни
Допустим, нужно быстро обработать JSON и сформировать отчёт. Используем System.Text.Json и CsvHelper:
#:package CsvHelper@33.1.0
using System.Text.Json;
using CsvHelper;
using System.Globalization;
using System.Text.Json.Serialization.Metadata;
var json = await
File.ReadAllTextAsync("sales_data.json");
var sales =
JsonSerializer.Deserialize<List<SaleRecord>>(
json,
new JsonSerializerOptions() {
TypeInfoResolver = new DefaultJsonTypeInfoResolver()
});
var topProducts = sales
.GroupBy(s => s.Product)
.Select(g => new {
Product = g.Key,
TotalRevenue = g.Sum(s => s.Amount),
UnitsSold = g.Count()
})
.OrderByDescending(p => p.TotalRevenue)
.Take(10);
using var writer =
new StreamWriter("top_products.csv");
using var csv =
new CsvWriter(writer, CultureInfo.InvariantCulture);
csv.WriteRecords(topProducts);
Console.WriteLine(
"Отчёт сохранён в top_products.csv");
record SaleRecord(string Product, decimal Amount, DateTime Date);
Заметьте, как мы используем и ссылки на NuGet-пакеты, и асинхронные операции, и LINQ, и записи — всё в одном файле, который читается как связный скрипт. Обычно для таких задач используется Python, но теперь можно остаться в C#.
Окончание следует…
Источник: https://www.milanjovanovic.tech/blog/exploring-csharp-file-based-apps-in-dotnet-10