.NET Core или .NET Standard: что выбрать для библиотеки? Полный гайд

Онлайн-тренажер Python для начинающих

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

Начать курс

Введение: Лабиринт .NET-библиотек

Если вы когда-нибудь создавали новый проект в Visual Studio или Rider, то наверняка видели два похожих, но сбивающих с толку шаблона: Class Library (.NET Core) и Class Library (.NET Standard). Возникает закономерный вопрос: «А в чем, собственно, разница? И что мне выбрать, чтобы потом не переписывать всё с нуля?».

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

1. Краткий экскурс в историю: от .NET Framework до эпохи унификации

Чтобы понять разницу, нужно вспомнить, как развивалась платформа. Раньше был только .NET Framework — монолитная среда для Windows. Затем появился .NET Core — кроссплатформенная, легковесная версия. И тут возникла проблема: как написать библиотеку, которая работала бы и там, и там? Для этого придумали .NET Standard — формальную спецификацию API, которые гарантированно есть во всех реализациях .NET.

Однако с выходом .NET 5 (и далее .NET 6, 7, 8) Microsoft объединила платформы. Теперь есть единый базовый класс — .NET (ранее .NET Core). Это сильно изменило правила игры. Давайте разберем, что это значит для нас, разработчиков.

2. Что такое Class Library (.NET Standard)?

.NET Standard — это не runtime, а набор контрактов. Представьте, что это «универсальный переходник». Если вы создаете библиотеку, нацеленную на netstandard2.0, она сможет работать:

  • В .NET Framework 4.6.1+
  • В .NET Core 2.0+
  • В .NET 5/6/7/8
  • В Xamarin, Mono, Unity и даже в UWP

Это идеальный выбор, если вам нужно максимальное покрытие платформ. Вы пишете код один раз — и он работает везде, где поддерживается эта версия стандарта.

Пример кода для .NET Standard библиотеки

Создадим простую библиотеку для работы со строками, нацеленную на netstandard2.0:

// StringHelper.cs
using System;
using System.Text.RegularExpressions;

namespace MyStandardLibrary
{
    public class StringHelper
    {
        /// <summary>
        /// Удаляет все HTML-теги из строки.
        /// </summary>
        public static string StripHtmlTags(string input)
        {
            if (string.IsNullOrEmpty(input))
                return string.Empty;

            // Простой, но эффективный regex для удаления тегов
            return Regex.Replace(input, "<.*?>", string.Empty);
        }

        /// <summary>
        /// Переворачивает строку задом наперед.
        /// </summary>
        public static string ReverseString(string input)
        {
            if (string.IsNullOrEmpty(input))
                return string.Empty;

            char[] chars = input.ToCharArray();
            Array.Reverse(chars);
            return new string(chars);
        }
    }
}

Обратите внимание: мы используем только базовые классы (System, System.Text.RegularExpressions), которые гарантированно есть во всех реализациях .NET Standard 2.0. Эта библиотека будет работать даже в проекте на .NET Framework 4.6.1, который Microsoft больше не развивает, но который до сих пор используется в корпоративном секторе.

3. Что такое Class Library (.NET Core / .NET)?

Когда вы выбираете .NET Core Class Library (или просто .NET Class Library, если у вас .NET 5+), вы привязываетесь к конкретной реализации платформы. В файле проекта (csproj) вы увидите что-то вроде <TargetFramework>net8.0</TargetFramework>.

Это дает вам доступ ко всем новейшим фишкам языка и API:

  • Span<T> и Memory<T> для высокопроизводительной работы с памятью.
  • Последние версии C# (records, primary constructors, etc.).
  • Специфичные для ОС API (через условную компиляцию).

Но плата за это — потеря совместимости. Ваша библиотека не будет работать в старом .NET Framework или Xamarin без дополнительных телодвижений.

Пример кода для .NET 8 библиотеки

Давайте реализуем ту же задачу, но с использованием современных возможностей:

// StringHelper.cs
using System;
using System.Text.RegularExpressions;

namespace MyModernLibrary
{
    public partial class StringHelper
    {
        /// <summary>
        /// Удаляет HTML-теги с использованием Source Generator для Regex.
        /// </summary>
        [GeneratedRegex("<.*?>")]
        private static partial Regex HtmlTagRegex();

        public static string StripHtmlTags(string input)
        {
            if (string.IsNullOrEmpty(input))
                return string.Empty;

            return HtmlTagRegex().Replace(input, string.Empty);
        }

        /// <summary>
        /// Переворачивает строку с использованием Span<T> (доступно только в .NET Core/.NET 5+).
        /// </summary>
        public static string ReverseString(string input)
        {
            if (string.IsNullOrEmpty(input))
                return string.Empty;

            // Используем Span для оптимизации производительности
            Span<char> span = input.ToCharArray();
            span.Reverse();
            return new string(span);
        }
    }
}

Видите разницу? Мы использовали [GeneratedRegex] — атрибут, который компилирует регулярное выражение во время сборки (доступен в .NET 7+). Также мы применили Span<char> для более быстрой работы с памятью. Если вы попытаетесь подключить эту библиотеку к проекту на .NET Framework 4.8, компилятор выдаст ошибку — этих API там просто нет.

4. Ключевые различия: когда что использовать?

Давайте сведем всё в таблицу, чтобы было наглядно:

Характеристика .NET Standard Library .NET Core / .NET Library
Совместимость Максимальная (работает на старых и новых платформах) Только .NET Core / .NET 5+
Доступ к новым API Ограничен версией стандарта Полный доступ к последним API
Производительность Базовая (без Span, без Source Generators) Максимальная (все оптимизации платформы)
Раз

Блоги

Рекомендаций по книгам