Share via


Gedeeltelijk lid (C#-verwijzing)

Een gedeeltelijk lid heeft één verklaring en vaak één uitvoeringsdeclaratie. De declaratie bevat geen hoofdtekst. De uitvoeringsverklaring voorziet in de hoofdtekst van het lid. Gedeeltelijke leden stellen klasontwerpers in staat lidhaken te bieden, vergelijkbaar met gebeurtenis-handlers, die ontwikkelaars kunnen besluiten om te implementeren of niet. Gedeeltelijke typen en leden bieden een manier voor menselijke ontwikkelaars om een deel van een type te schrijven terwijl hulpprogramma's andere delen van het type schrijven. Als de ontwikkelaar geen optionele implementatiedeclaratie levert, kan de compiler de declaratie op het moment van compileren verwijderen. De volgende voorwaarden zijn van toepassing op gedeeltelijke leden:

  • Declaraties moeten beginnen met het contextuele trefwoord gedeeltelijk.
  • Handtekeningen in beide delen van het gedeeltelijke type moeten overeenkomen.

Het partial trefwoord is niet toegestaan voor constructors, finalizers, overbelaste operators of gebeurtenisdeclaraties. Vóór C# 13 was partial het niet toegestaan voor eigenschappen of indexeerfuncties.

Een gedeeltelijke methode is in de volgende gevallen niet vereist om een uitvoeringsdeclaratie te hebben:

  • Het heeft geen toegankelijkheidsaanpassingen (inclusief de standaardinstelling private).
  • Het retourneert void.
  • Er zijn out geen parameters.
  • Het heeft geen van de volgende modifiers virtual, , override, sealedof newextern.

Elk lid dat niet voldoet aan al deze beperkingen (bijvoorbeeld een public virtual partial void methode), moet een implementatie bieden. Gedeeltelijke eigenschappen en indexeerfuncties moeten een implementatie hebben.

In het volgende voorbeeld ziet u een gedeeltelijke methode die voldoet aan de voorgaande beperkingen:

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

Gedeeltelijke leden kunnen ook handig zijn in combinatie met brongeneratoren. Een regex kan bijvoorbeeld worden gedefinieerd met behulp van het volgende patroon:

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

In het voorgaande voorbeeld ziet u een gedeeltelijke methode die een uitvoeringsdeclaratie moet hebben. Als onderdeel van een build maakt de brongenerator voor reguliere expressies de implementatiedeclaratie.

In het volgende voorbeeld ziet u een declaratie en een uitvoeringsdeclaratie voor een klasse. Omdat het retourtype van de methode niet void (het is string) en de toegang is public, moet de methode een uitvoeringsdeclaratie hebben:

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

In het voorgaande voorbeeld ziet u regels voor hoe de twee declaraties worden gecombineerd:

  • Overeenkomsten met handtekening: Over het algemeen moeten de handtekeningen voor de declaraties en de uitvoering van declaraties overeenkomen. Dit omvat toegankelijkheidsaanpassing voor methoden, eigenschappen, indexeerfuncties en afzonderlijke accessors. Het bevat het parametertype en ref-kind modifiers voor alle parameters. Het retourtype en elke ref-kind modifier moeten overeenkomen. Namen van tuple-leden moeten overeenkomen. Sommige regels zijn echter flexibel:
    • De declaratie- en implementatiedeclaraties kunnen verschillende instellingen voor null-aantekeningen hebben. Dit betekent dat de ene waarde nullable kan zijn en dat de andere nullable is ingeschakeld.
    • Verschillen in nullabiliteit waarbij geen sprake is van vergetelheid bij null-waarden , genereert een waarschuwing.
    • Standaardparameterwaarden hoeven niet overeen te komen. De compiler geeft een waarschuwing uit als de implementatiedeclaratie van een methode of indexeerfunctie een standaardparameterwaarde declareert.
    • De compiler geeft een waarschuwing wanneer parameternamen niet overeenkomen. De verzonden IL bevat de parameternamen van de declaratiedeclaratie.
  • Opmerkingen bij documentatie: Documentatieopmerkingen kunnen worden opgenomen uit een van beide declaraties. Als zowel de declaratie- als de implementatiedeclaraties documentatieopmerkingen bevatten, worden de opmerkingen uit de uitvoeringsdeclaratie opgenomen. In het voorgaande voorbeeld zijn de opmerkingen bij de documentatie onder andere:
    • Voor de Capacity eigenschap worden de opmerkingen uit de uitvoeringsdeclaratie genomen. De opmerkingen bij de uitvoering van declaraties worden gebruikt wanneer beide declaraties opmerkingen bevatten /// .
    • Voor de indexeerfunctie worden de opmerkingen uit de declaratie genomen. De implementatiedeclaratie bevat /// geen opmerkingen.
    • Hiervoor TryGetAtworden de opmerkingen uit de uitvoeringsverklaring genomen. De declaratie bevat /// geen opmerkingen.
    • De gegenereerde XML bevat documentatieopmerkingen voor alle public leden.
  • De meeste kenmerkdeclaraties worden gecombineerd. Alle kenmerken van bellergegevens worden echter gedefinieerd met AllowMultiple=false. De compiler herkent elk infokenmerk van de aanroeper in de declaratiedeclaratie. Alle infokenmerken van de beller in de implementatiedeclaratie worden genegeerd. De compiler geeft een waarschuwing als u informatiekenmerken van de aanroeper toevoegt aan de implementatiedeclaratie.

Zie ook