Поделиться через


Частичный член (справочник по 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помощью . Компилятор распознает любой атрибут сведений о вызывающем объекте в объявлении. Все атрибуты сведений о вызывающем объекте в объявлении реализации игнорируются. Компилятор выдает предупреждение при добавлении атрибутов сведений о вызывающем объекте в объявление реализации.

См. также