Delen via


interface (C#-verwijzing)

Een interface definieert een contract. Elke class, of struct die dat contract implementeert, record moet een implementatie bieden van de leden die in de interface zijn gedefinieerd. Een interface kan een standaard implementatie definiëren voor leden. Het kan ook leden definiëren static om één implementatie te bieden voor algemene functionaliteit. Vanaf C# 11 kan een interface definiëren static abstract of static virtual leden declareren dat een implementatietype de gedeclareerde leden moet leveren. static virtual Methoden verklaren doorgaans dat een implementatie een set overbelaste operators moet definiëren.

In het volgende voorbeeld moet de klasse ImplementationClass een methode implementeren die SampleMethod geen parameters bevat en retourneert void.

Zie Interfaces voor meer informatie en voorbeelden.

Een interface op het hoogste niveau, die is gedeclareerd in een naamruimte, maar niet genest binnen een ander type, kan worden gedeclareerd public of internal. De standaardwaarde is internal. Geneste interfacedeclaraties, die binnen een ander type zijn gedeclareerd, kunnen worden gedeclareerd met behulp van elke toegangsaanpassing.

Interfaceleden zonder een implementatie kunnen geen toegangsmodifier bevatten. Leden met een standaard implementatie kunnen alle toegangsaanpassingen bevatten.

Voorbeeldinterface

interface ISampleInterface
{
    void SampleMethod();
}

class ImplementationClass : ISampleInterface
{
    // Explicit interface member implementation:
    void ISampleInterface.SampleMethod()
    {
        // Method implementation.
    }

    static void Main()
    {
        // Declare an interface instance.
        ISampleInterface obj = new ImplementationClass();

        // Call the member.
        obj.SampleMethod();
    }
}

Een interface kan lid zijn van een naamruimte of een klasse. Een interfacedeclaratie kan declaraties (handtekeningen zonder enige implementatie) van de volgende leden bevatten:

Standaardinterfaceleden

Deze voorgaande liddeclaraties bevatten doorgaans geen hoofdtekst. Een interfacelid kan een hoofdtekst declareren. Leden in een interface zijn de standaard implementatie. Leden met lichamen stellen de interface in staat om een 'standaard'-implementatie te bieden voor klassen en structs die geen overschrijvende implementatie bieden.

Belangrijk

Het toevoegen van standaardinterfaceleden dwingt alle ref struct gebruikers die de interface implementeren om een expliciete declaratie van dat lid toe te voegen.

Een interface kan het volgende omvatten:

Statische abstracte en virtuele leden

Vanaf C# 11 kan een interface declareren en static virtual leden voor static abstract alle lidtypen behalve velden. Interfaces kunnen aangeven dat het implementeren van typen operators of andere statische leden moet definiëren. Met deze functie kunnen algemene algoritmen het gedrag van getallen opgeven. U kunt voorbeelden zien in de numerieke typen in de .NET-runtime, zoals System.Numerics.INumber<TSelf>. Deze interfaces definiëren algemene wiskundige operatoren die door veel numerieke typen worden geïmplementeerd. De compiler moet aanroepen en static virtual static abstract methoden tijdens het compileren oplossen. De static virtual methoden die static abstract in interfaces zijn gedeclareerd, hebben geen runtime-verzendmechanisme dat vergelijkbaar is met virtual of abstract methoden die zijn gedeclareerd in klassen. In plaats daarvan gebruikt de compiler typegegevens die beschikbaar zijn tijdens het compileren. static virtual Daarom worden methoden bijna uitsluitend gedeclareerd in algemene interfaces. Bovendien moeten de meeste interfaces die declareren of methoden declareren static virtual dat een van de typeparameters de gedeclareerde interface moet implementeren.static abstract De interface declareert bijvoorbeeld INumber<T> dat T moet worden geïmplementeerd INumber<T>. De compiler gebruikt het typeargument om aanroepen naar de methoden en operators om te voeren die zijn gedeclareerd in de interfacedeclaratie. Het type implementeert INumber<int>bijvoorbeeld int . Wanneer de typeparameter het typeargument T intaangeeft, worden de static leden aangeroepen die zijn gedeclareerd int . double Als het typeargument is, worden de static leden die voor het double type zijn gedeclareerd, ook aangeroepen.

Belangrijk

Methode-verzending voor static abstract en static virtual methoden die in interfaces zijn gedeclareerd, wordt opgelost met behulp van het type compileertijd van een expressie. Als het runtimetype van een expressie is afgeleid van een ander type compileertijd, worden de statische methoden op het basistype (compileertijd) aangeroepen.

U kunt deze functie proberen door te werken met de zelfstudie over statische abstracte leden in interfaces.

Overname van interface

Interfaces bevatten mogelijk geen exemplaarstatus. Statische velden zijn nu toegestaan, maar exemplaarvelden zijn niet toegestaan in interfaces. Automatische eigenschappen van exemplaren worden niet ondersteund in interfaces, omdat ze impliciet een verborgen veld declareren. Deze regel heeft een subtiel effect op eigenschapsdeclaraties. In een interfacedeclaratie declareert de volgende code geen automatisch geïmplementeerde eigenschap zoals in een class of struct. In plaats daarvan declareert het een eigenschap die geen standaard implementatie heeft, maar moet worden geïmplementeerd in elk type dat de interface implementeert:

public interface INamed
{
  public string Name {get; set;}
}

Een interface kan overnemen van een of meer basisinterfaces. Wanneer een interface wordt overgenomen van een andere interface, moet een type dat de afgeleide interface implementeert alle leden in de basisinterfaces implementeren, evenals de leden die zijn gedeclareerd in de afgeleide interface, zoals wordt weergegeven in de volgende code:

public interface I1
{
    void M1();
}

public interface I2 : I1
{
    void M2();
}

public class C : I2
{
    // implements I1.M1
    public void M1() { }
    // implements I2.M2
    public void M2() { }
}

Wanneer een interface een methode overschrijft die is geïmplementeerd in een basisinterface, moet deze de expliciete syntaxis van de interface-implementatie gebruiken.

Wanneer een basistypelijst een basisklasse en interfaces bevat, moet de basisklasse eerst in de lijst komen.

Een klasse die een interface implementeert, kan expliciet leden van die interface implementeren. Een expliciet geïmplementeerd lid kan niet worden geopend via een klasse-exemplaar, maar alleen via een exemplaar van de interface. Daarnaast kunnen standaardinterfaceleden alleen worden geopend via een exemplaar van de interface.

Zie Expliciete interface-implementatie voor meer informatie over expliciete interface-implementatie.

Voorbeeld van interface-implementatie

In het volgende voorbeeld ziet u de interface-implementatie. In dit voorbeeld bevat de interface de eigenschapsdeclaratie en bevat de klasse de implementatie. Elk exemplaar van een klasse die implementeertIPoint, heeft gehele getallen en yx .

interface IPoint
{
    // Property signatures:
    int X { get; set; }

    int Y { get; set; }

    double Distance { get; }
}

class Point : IPoint
{
    // Constructor:
    public Point(int x, int y)
    {
        X = x;
        Y = y;
    }

    // Property implementation:
    public int X { get; set; }

    public int Y { get; set; }

    // Property implementation
    public double Distance =>
       Math.Sqrt(X * X + Y * Y);
}

class MainClass
{
    static void PrintPoint(IPoint p)
    {
        Console.WriteLine("x={0}, y={1}", p.X, p.Y);
    }

    static void Main()
    {
        IPoint p = new Point(2, 3);
        Console.Write("My Point: ");
        PrintPoint(p);
    }
}
// Output: My Point: x=2, y=3

C#-taalspecificatie

Zie de sectie Interfaces van de C#-taalspecificatie, de functiespecificatie voor C# 8 - Standaardinterfaceleden en de functiespecificatie voor C# 11 - statische abstracte leden in interfaces

Zie ook