Частичный член (справочник по C#)

Частичный член имеет одно объявление об объявлении и часто одно реализующее объявление. Объявление объявления не включает текст. Объявление реализации предоставляет текст элемента. Частичные члены позволяют конструкторам классов предоставлять перехватчики элементов, аналогичные обработчикам событий, которые разработчики могут решить реализовать или нет. Частичные типы и члены предоставляют разработчикам возможность писать часть типа, а средства записывают другие части типа. Если разработчик не предоставляет необязательное объявление реализации, компилятор может удалить объявление объявления во время компиляции. Следующие условия применяются к частичным элементам:

  • Объявления должны начинаться с контекстного ключевого слова partial.
  • Сигнатуры в обеих частях разделяемого типа должны совпадать.

Ключевое partial слово не допускается для конструкторов, завершения, перегруженных операторов или объявлений событий. До C# 13 partial не было разрешено для свойств или индексаторов.

Частичный метод не требуется для объявления реализации в следующих случаях:

  • У него нет модификаторов специальных возможностей (включая стандартные private).
  • Он возвращает void.
  • У него нет out параметров.
  • У него нет ни одного из следующих модификаторовvirtual, override, , sealedили newextern.

Любой элемент, который не соответствует всем этим ограничениям (например, public virtual partial void методу), должен предоставить реализацию. Частичные свойства и индексаторы должны иметь реализацию.

В следующем примере показан частичный метод, соответствующий предыдущим ограничениям:

partial class MyPartialClass
{
    // Declaring definition
    partial void OnSomethingHappened(string s);
}

// This part can be in a separate file.
partial class MyPartialClass
{
    // Comment out this method and the program
    // will still compile.
    partial void OnSomethingHappened(string s) =>
        Console.WriteLine($"Something happened: {s}");
}

Частичные члены также могут быть полезны в сочетании с генераторами источников. Например, можно определить регулярное выражение, используя следующий шаблон.

public partial class RegExSourceGenerator
{
    [GeneratedRegex("cat|dog", RegexOptions.IgnoreCase, "en-US")]
    private static partial Regex CatOrDogGeneratedRegex();

    private static void EvaluateText(string text)
    {
        if (CatOrDogGeneratedRegex().IsMatch(text))
        {
            // Take action with matching text
        }
    }
}

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

В следующем примере показана декларативная объявление и реализация объявления для класса. Так как возвращаемый тип метода не void является ( stringэто) и его доступом publicявляется, метод должен иметь объявление реализации:

// Declaring declaration
public partial class PartialExamples
{
    /// <summary>
    /// Gets or sets the number of elements that the List can contain.
    /// </summary>
    public partial int Capacity { get; set; }

    /// <summary>
    /// Gets or sets the element at the specified index.
    /// </summary>
    /// <param name="index">The index</param>
    /// <returns>The string stored at that index</returns>
    public partial string this[int index] { get; set; }

    public partial string? TryGetAt(int index);
}

public partial class PartialExamples
{
    private List<string> _items = [
        "one",
        "two",
        "three",
        "four",
        "five"
        ];

    // Implementing declaration

    /// <summary>
    /// Gets or sets the number of elements that the List can contain.
    /// </summary>
    /// <remarks>
    /// If the value is less than the current capacity, the list will shrink to the
    /// new value. If the value is negative, the list isn't modified.
    /// </remarks>
    public partial int Capacity
    {
        get => _items.Count;
        set
        {
            if ((value != _items.Count) && (value >= 0))
            {
                _items.Capacity = value;
            }
        }
    }

    public partial string this[int index]
    {
        get => _items[index];
        set => _items[index] = value;
    }

    /// <summary>
    /// Gets the element at the specified index.
    /// </summary>
    /// <param name="index">The index</param>
    /// <returns>The string stored at that index, or null if out of bounds</returns>
    public partial string? TryGetAt(int index)
    {
        if (index < _items.Count)
        {
            return _items[index];
        }
        return null;
    }
}

В предыдущем примере показаны правила объединения двух объявлений:

  • Совпадения подписей: в целом подписи для объявления и реализации объявлений должны соответствовать. Это включает модификатор специальных возможностей для методов, свойств, индексаторов и отдельных методов доступа. Он включает в себя тип параметров и модификаторы типа ссылок для всех параметров. Возвращаемый тип и любой модификатор типа ссылок должен соответствовать. Имена элементов кортежа должны совпадать. Однако некоторые правила являются гибкими:
    • Декларируемые и реализующие объявления могут иметь разные параметры заметки, допускающие значение NULL. Это означает, что один из них может быть пустым и другим включенным значением NULL.
    • Различия в доступности NULL, не связанные с забвительным значением NULL, создают предупреждение.
    • Значения параметров по умолчанию не должны соответствовать. Компилятор выдает предупреждение, если реализация объявления метода или индексатора объявляет значение параметра по умолчанию.
    • Компилятор выдает предупреждение, если имена параметров не совпадают. Создаваемый IL содержит имена параметров объявления.
  • Комментарии к документации: комментарии к документации можно включить из любого объявления. Если декларативные и реализующие объявления включают комментарии к документации, будут включены комментарии из реализующего объявления. В предыдущем примере комментарии документации включают:
    • Capacity Для свойства комментарии принимаются из объявления реализации. Примечания реализации объявлений используются, когда оба объявления имеют /// примечания.
    • Для индексатора комментарии принимаются из объявления объявления. В объявлении реализации нет /// комментариев.
    • Для TryGetAtэтого комментарии взяты из реализуемого объявления. Объявление объявления не содержит /// комментариев.
    • Созданный XML содержит комментарии документации для всех public участников.
  • Большинство объявлений атрибутов объединяются. Однако все атрибуты сведений о вызывающем объекте определяются с AllowMultiple=falseпомощью . Компилятор распознает любой атрибут сведений о вызывающем объекте в объявлении. Все атрибуты сведений о вызывающем объекте в объявлении реализации игнорируются. Компилятор выдает предупреждение при добавлении атрибутов сведений о вызывающем объекте в объявление реализации.

См. также