Sdílet prostřednictvím


Částečný člen (Referenční dokumentace jazyka C#)

Částečný člen má jednu deklarující deklaraci a často jednu implementující deklaraci. Deklarace deklarace neobsahuje tělo. Prováděcí deklarace obsahuje tělo člena. Částečné členy umožňují návrhářům tříd poskytovat členové háky, které lze implementovat pomocí nástrojů, jako jsou generátory zdrojů. Částečné typy a členové poskytují vývojářům způsob, jak psát část typu, zatímco nástroje zapisují další části typu. Pokud vývojář nezadá volitelnou implementaci deklarace, kompilátor může deklaraci deklarace v době kompilace odebrat. Následující podmínky platí pro částečné členy:

  • Deklarace musí začínat kontextovým klíčovým slovem částečným.
  • Podpisy v obou částech částečného typu se musí shodovat.

Klíčové partial slovo není povoleno u konstruktorů, finalizátorů, přetížených operátorů nebo deklarací událostí. Před C# 13 partial nebyla povolena pro vlastnosti ani indexery.

Částečná metoda není nutná k implementaci deklarace v následujících případech:

Každý člen, který nevyhovuje všem těmto omezením (například public virtual partial void metodě), musí poskytnout implementaci. Částečné vlastnosti a indexery musí mít implementaci.

Následující příklad ukazuje částečnou metodu, která odpovídá předchozím omezením:

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}");
}

Částečné členy mohou být také užitečné v kombinaci se zdrojovými generátory. Například regulární výraz lze definovat pomocí následujícího vzoru:

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
        }
    }
}

Předchozí příklad ukazuje částečnou metodu, která musí mít implementující deklaraci. V rámci sestavení vytvoří generátor zdroje regulárních výrazů implementovou deklaraci.

Následující příklad ukazuje deklarující deklaraci a implementující deklaraci třídy. Vzhledem k tomu, že návratový typ metody není void (je string) a jeho přístup je public, musí mít metoda implementční deklaraci:

// 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;
    }
}

Předchozí příklad znázorňuje pravidla, jak se obě deklarace zkombinují:

  • Shoda s podpisem: Obecně platí, že podpisy pro deklarování a implementaci deklarací se musí shodovat. To zahrnuje modifikátor přístupnosti u metod, vlastností, indexerů a jednotlivých přístupových objektů. Zahrnuje typ parametru a modifikátory typu ref-kind pro všechny parametry. Návratový typ a jakýkoli modifikátor typu ref se musí shodovat. Názvy členů řazené kolekce členů se musí shodovat. Některá pravidla jsou ale flexibilní:
    • Deklarace a implementace deklarací můžou mít různá nastavení poznámek s možnou hodnotou null. To znamená, že jedna může být obživitelná a druhá povolena s možnou hodnotou null.
    • Rozdíly s nulovostí, které nezahrnují obživu, vygeneruje upozornění.
    • Výchozí hodnoty parametrů se nemusí shodovat. Kompilátor vydá upozornění, pokud implementace deklarace metody nebo indexer deklaruje výchozí hodnotu parametru.
    • Kompilátor vydá upozornění, když se názvy parametrů neshodují. Vygenerovaný il obsahuje deklarující názvy parametrů deklarace.
  • Komentáře k dokumentaci: Komentáře k dokumentaci lze zahrnout z obou deklarací. Pokud deklarace i implementace deklarací obsahují komentáře k dokumentaci, budou zahrnuty komentáře z prováděcí deklarace. V předchozím příkladu patří komentáře k dokumentaci:
    • Capacity Pro vlastnost jsou komentáře převzaty z prováděcí deklarace. Implementační komentáře k deklaraci se použijí, když obě deklarace obsahují /// komentáře.
    • U indexeru jsou komentáře převzaty z deklarace deklarace. Implementační deklarace neobsahuje žádné /// komentáře.
    • V TryGetAtpřípadě , komentáře jsou převzaty z prováděcí deklarace. Deklarace deklarace neobsahuje žádné /// komentáře.
    • Vygenerovaný XML obsahuje komentáře k dokumentaci pro všechny public členy.
  • Většina deklarací atributů se zkombinuje. Všechny atributy informací o volajícím jsou však definovány pomocí AllowMultiple=false. Kompilátor rozpozná jakýkoli atribut informací o volajícím deklarující deklaraci. Všechny atributy informací o volajícím v implementaci deklarace jsou ignorovány. Kompilátor vydá upozornění, pokud do implementační deklarace přidáte atributy informací o volajícím.

Viz také