Share via


Gedeeltelijke klassen en methoden (C#-programmeerhandleiding)

Het is mogelijk om de definitie van een klasse, een struct, een interface of een methode over twee of meer bronbestanden te splitsen. Elk bronbestand bevat een sectie van het type of de methodedefinitie en alle onderdelen worden gecombineerd wanneer de toepassing wordt gecompileerd.

Gedeeltelijke klassen

Er zijn verschillende situaties waarin het splitsen van een klassedefinitie wenselijk is:

  • Door een klasse over afzonderlijke bestanden te declareren, kunnen meerdere programmeurs er tegelijkertijd aan werken.
  • U kunt code toevoegen aan de klasse zonder dat u het bronbestand dat automatisch gegenereerde bron bevat, opnieuw hoeft te maken. Visual Studio maakt gebruik van deze benadering bij het maken van Windows Forms, webservice-wrappercode, enzovoort. U kunt code maken die gebruikmaakt van deze klassen zonder dat u het bestand hoeft te wijzigen dat is gemaakt door Visual Studio.
  • Brongeneratoren kunnen extra functionaliteit genereren in een klasse.

Als u een klassedefinitie wilt splitsen, gebruikt u de gedeeltelijke wijziging van trefwoorden, zoals hier wordt weergegeven:

public partial class Employee
{
    public void DoWork()
    {
    }
}

public partial class Employee
{
    public void GoToLunch()
    {
    }
}

Het partial trefwoord geeft aan dat andere onderdelen van de klasse, struct of interface kunnen worden gedefinieerd in de naamruimte. Alle onderdelen moeten het partial trefwoord gebruiken. Alle onderdelen moeten tijdens het compileren beschikbaar zijn om het uiteindelijke type te vormen. Alle onderdelen moeten dezelfde toegankelijkheid hebben, zoals public, privateenzovoort.

Als een deel abstract wordt gedeclareerd, wordt het hele type beschouwd als abstract. Als een deel wordt gedeclareerd als verzegeld, wordt het hele type beschouwd als verzegeld. Als een deel een basistype declareert, neemt het hele type die klasse over.

Alle onderdelen die een basisklasse opgeven, moeten akkoord gaan, maar delen die een basisklasse weglaten, nemen nog steeds het basistype over. Onderdelen kunnen verschillende basisinterfaces opgeven en het uiteindelijke type implementeert alle interfaces die worden vermeld door alle gedeeltelijke declaraties. Alle klasse-, struct- of interfaceleden die in een gedeeltelijke definitie zijn gedeclareerd, zijn beschikbaar voor alle andere onderdelen. Het uiteindelijke type is de combinatie van alle onderdelen tijdens het compileren.

Notitie

De partial wijzigingsfunctie is niet beschikbaar voor declaraties voor gemachtigden of opsommingen.

In het volgende voorbeeld ziet u dat geneste typen gedeeltelijk kunnen zijn, zelfs als het type waarin ze zijn genest, niet gedeeltelijk zelf is.

class Container
{
    partial class Nested
    {
        void Test() { }
    }

    partial class Nested
    {
        void Test2() { }
    }
}

Tijdens het compileren worden kenmerken van gedeeltelijke definities samengevoegd. Denk bijvoorbeeld aan de volgende declaraties:

[SerializableAttribute]
partial class Moon { }

[ObsoleteAttribute]
partial class Moon { }

Ze zijn gelijk aan de volgende declaraties:

[SerializableAttribute]
[ObsoleteAttribute]
class Moon { }

Hieronder worden alle gedeeltelijke definities samengevoegd:

  • XML-opmerkingen
  • Interfaces
  • parameterkenmerken van het type generic
  • klassekenmerken
  • leden

Denk bijvoorbeeld aan de volgende declaraties:

partial class Earth : Planet, IRotate { }
partial class Earth : IRevolve { }

Ze zijn gelijk aan de volgende declaraties:

class Earth : Planet, IRotate, IRevolve { }

Beperkingen

Er zijn verschillende regels die u moet volgen wanneer u werkt met gedeeltelijke klassedefinities:

  • Alle gedeeltelijke definities die zijn bedoeld om onderdelen van hetzelfde type te zijn, moeten worden gewijzigd met partial. Met de volgende klassedeclaraties wordt bijvoorbeeld een fout gegenereerd:
    public partial class A { }
    //public class A { }  // Error, must also be marked partial
    
  • De partial wijzigingsfunctie kan alleen direct vóór het trefwoord class, structof interface.
  • Geneste gedeeltelijke typen zijn toegestaan in definities van gedeeltelijk type, zoals wordt geïllustreerd in het volgende voorbeeld:
    partial class ClassWithNestedClass
    {
        partial class NestedClass { }
    }
    
    partial class ClassWithNestedClass
    {
        partial class NestedClass { }
    }
    
  • Alle gedeeltelijke definities die zijn bedoeld om onderdelen van hetzelfde type te zijn, moeten worden gedefinieerd in dezelfde assembly en dezelfde module (.exe of .dll bestand). Gedeeltelijke definities kunnen niet meerdere modules omvatten.
  • De klassenaam en de algemene parameters moeten overeenkomen met alle definities van het gedeeltelijke type. Algemene typen kunnen gedeeltelijk zijn. Elke gedeeltelijke declaratie moet dezelfde parameternamen in dezelfde volgorde gebruiken.
  • De volgende trefwoorden voor een definitie van een gedeeltelijk type zijn optioneel, maar als deze aanwezig zijn op een gedeeltelijke definitie, kan het niet conflicteren met de trefwoorden die zijn opgegeven in een andere gedeeltelijke definitie voor hetzelfde type:

Zie Beperkingen voor typeparameters voor meer informatie.

Voorbeelden

In het volgende voorbeeld worden de velden en de constructor van de klasse gedeclareerd Coordsin één gedeeltelijke klassedefinitie en wordt het lid PrintCoordsgedeclareerd in een andere gedeeltelijke klassedefinitie.

public partial class Coords
{
    private int x;
    private int y;

    public Coords(int x, int y)
    {
        this.x = x;
        this.y = y;
    }
}

public partial class Coords
{
    public void PrintCoords()
    {
        Console.WriteLine("Coords: {0},{1}", x, y);
    }
}

class TestCoords
{
    static void Main()
    {
        Coords myCoords = new Coords(10, 15);
        myCoords.PrintCoords();

        // Keep the console window open in debug mode.
        Console.WriteLine("Press any key to exit.");
        Console.ReadKey();
    }
}
// Output: Coords: 10,15

In het volgende voorbeeld ziet u dat u ook gedeeltelijke structs en interfaces kunt ontwikkelen.

partial interface ITest
{
    void Interface_Test();
}

partial interface ITest
{
    void Interface_Test2();
}

partial struct S1
{
    void Struct_Test() { }
}

partial struct S1
{
    void Struct_Test2() { }
}

Gedeeltelijke methoden

Een gedeeltelijke klasse of struct kan een gedeeltelijke methode bevatten. Een deel van de klasse bevat de handtekening van de methode. Een implementatie kan worden gedefinieerd in hetzelfde deel of een ander onderdeel.

Een implementatie is niet vereist voor een gedeeltelijke methode wanneer de handtekening voldoet aan de volgende regels:

  • De declaratie bevat geen toegangsaanpassingen. De methode heeft private standaard toegang.
  • Het retourtype is void.
  • Geen van de parameters heeft de out wijzigingsfunctie.
  • De methodedeclaratie kan geen van de volgende modifiers bevatten:

De methode en alle aanroepen naar de methode worden tijdens het compileren verwijderd wanneer er geen implementatie is.

Elke methode die niet voldoet aan al deze beperkingen (bijvoorbeeld public virtual partial void een methode), moet een implementatie bieden. Deze implementatie kan worden geleverd door een brongenerator.

Met gedeeltelijke methoden kan de implementeerfunctie van één deel van een klasse een methode declareren. De implementeerfunctie van een ander deel van de klasse kan die methode definiëren. Er zijn twee scenario's waarin deze scheiding nuttig is: sjablonen die standaardcode genereren en brongeneratoren.

  • Sjablooncode: De sjabloon reserveert een methodenaam en handtekening, zodat gegenereerde code de methode kan aanroepen. Deze methoden volgen de beperkingen waarmee een ontwikkelaar kan bepalen of de methode moet worden geïmplementeerd. Als de methode niet is geïmplementeerd, verwijdert de compiler de handtekening van de methode en alle aanroepen naar de methode. De aanroepen naar de methode, met inbegrip van eventuele resultaten van de evaluatie van argumenten in de aanroepen, hebben geen effect tijdens runtime. Daarom kan elke code in de gedeeltelijke klasse vrijelijk een gedeeltelijke methode gebruiken, zelfs als de implementatie niet wordt geleverd. Er zijn geen compileer- of runtimefouten als de methode wordt aangeroepen, maar niet is geïmplementeerd.
  • Brongeneratoren: Brongeneratoren bieden een implementatie voor methoden. De menselijke ontwikkelaar kan de methodedeclaratie toevoegen (vaak met kenmerken die door de brongenerator worden gelezen). De ontwikkelaar kan code schrijven die deze methoden aanroept. De brongenerator wordt uitgevoerd tijdens de compilatie en levert de implementatie. In dit scenario worden de beperkingen voor gedeeltelijke methoden die mogelijk niet worden geïmplementeerd, vaak niet gevolgd.
// Definition in file1.cs
partial void OnNameChanged();

// Implementation in file2.cs
partial void OnNameChanged()
{
  // method body
}
  • Gedeeltelijke methodedeclaraties moeten beginnen met het contextuele trefwoord gedeeltelijk.
  • Gedeeltelijke methodehandtekeningen in beide delen van het gedeeltelijke type moeten overeenkomen.
  • Gedeeltelijke methoden kunnen statische en onveilige modifiers hebben.
  • Gedeeltelijke methoden kunnen algemeen zijn. Beperkingen moeten hetzelfde zijn voor de declaratie van de definitie- en implementatiemethode. Parameter- en typeparameternamen hoeven niet hetzelfde te zijn in de implementatiedeclaratie als in het definiëren van de declaratie.
  • U kunt een gedelegeerde maken voor een gedeeltelijke methode die is gedefinieerd en geïmplementeerd, maar niet voor een gedeeltelijke methode die geen implementatie heeft.

C#-taalspecificatie

Zie Gedeeltelijke typen en Gedeeltelijke methoden in de C#-taalspecificatie voor meer informatie. De taalspecificatie is de definitieve bron voor de C#-syntaxis en het gebruik. De extra functies voor gedeeltelijke methoden worden gedefinieerd in de functiespecificatie.

Zie ook