interface (C#-referens)

Ett gränssnitt definierar ett kontrakt. Alla class, record eller struct som implementerar det kontraktet måste tillhandahålla en implementering av de medlemmar som definierats i gränssnittet. Ett gränssnitt kan definiera en standardimplementering för medlemmar. Det kan också definiera static medlemmar för att tillhandahålla en enda implementering för vanliga funktioner. Från och med C# 11 kan ett gränssnitt definiera static abstract eller static virtual medlemmar för att deklarera att en implementeringstyp måste ange de deklarerade medlemmarna. Vanligtvis static virtual deklarerar metoder att en implementering måste definiera en uppsättning överlagrade operatorer.

I följande exempel måste klassen ImplementationClass implementera en metod med namnet SampleMethod som inte har några parametrar och returnerar void.

Mer information och exempel finns i Gränssnitt.

Exempelgränssnitt

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

Ett gränssnitt kan vara medlem i ett namnområde eller en klass. En gränssnittsdeklaration kan innehålla deklarationer (signaturer utan implementering) av följande medlemmar:

Standardgränssnittsmedlemmar

Dessa föregående medlemsdeklarationer innehåller vanligtvis inte någon brödtext. En gränssnittsmedlem kan deklarera en brödtext. Medlemsorgan i ett gränssnitt är standardimplementeringen. Medlemmar med organ tillåter gränssnittet att tillhandahålla en "standardimplementering" för klasser och structs som inte tillhandahåller en övergripande implementering. Ett gränssnitt kan innehålla:

Statiska abstrakta och virtuella medlemmar

Från och med C# 11 kan ett gränssnitt deklarera static abstract och static virtual medlemmar för alla medlemstyper utom fält. Gränssnitt kan deklarera att implementeringstyper måste definiera operatorer eller andra statiska medlemmar. Med den här funktionen kan allmänna algoritmer ange talliknande beteende. Du kan se exempel i de numeriska typerna i .NET-körningen, till exempel System.Numerics.INumber<TSelf>. Dessa gränssnitt definierar vanliga matematiska operatorer som implementeras av många numeriska typer. Kompilatorn måste matcha anrop till static virtual och static abstract metoder vid kompileringstillfället. Metoderna static virtual och static abstract som deklareras i gränssnitten har inte någon runtime dispatch-mekanism som motsvarar virtual eller abstract metoder som deklarerats i klasser. Kompilatorn använder i stället typinformation som är tillgänglig vid kompileringstillfället. Därför static virtual deklareras metoder nästan uteslutande i generiska gränssnitt. Dessutom deklarerar de flesta gränssnitt som deklarerar static virtual eller static abstract metoder att en av typparametrarna måste implementera det deklarerade gränssnittet. Till exempel INumber<T> deklarerar gränssnittet som T måste implementera INumber<T>. Kompilatorn använder typargumentet för att lösa anrop till de metoder och operatorer som deklareras i gränssnittsdeklarationen. Typen implementerar INumber<int>till exempel int . När typparametern T anger typargumentet intanropas de medlemmar som static deklareras på int . Alternativt anropas de static medlemmar som deklarerats för typen när double är typargumentetdouble.

Viktigt!

Metodsändning för och static virtual metoder som deklarerats i gränssnitt löses med hjälp av kompileringstidstypen för static abstract ett uttryck. Om körningstypen för ett uttryck härleds från en annan kompileringstidstyp anropas de statiska metoderna på bastypen (kompileringstid).

Du kan prova den här funktionen genom att arbeta med självstudien om statiska abstrakta medlemmar i gränssnitt.

Gränssnittsarv

Gränssnitt får inte innehålla instanstillstånd. Statiska fält tillåts nu, men instansfält tillåts inte i gränssnitt. Autoegenskaper för instanser stöds inte i gränssnitt, eftersom de implicit deklarerar ett dolt fält. Den här regeln har en subtil effekt på egenskapsdeklarationer. I en gränssnittsdeklaration deklarerar inte följande kod en automatiskt implementerad egenskap som den gör i en class eller struct. I stället deklareras en egenskap som inte har någon standardimplementering, men som måste implementeras i alla typer som implementerar gränssnittet:

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

Ett gränssnitt kan ärva från ett eller flera basgränssnitt. När ett gränssnitt åsidosätter en metod som implementerats i ett basgränssnitt måste det använda den explicita syntaxen för gränssnittsimplementering .

När en bastyplista innehåller en basklass och gränssnitt måste basklassen komma först i listan.

En klass som implementerar ett gränssnitt kan uttryckligen implementera medlemmar i gränssnittet. En explicit implementerad medlem kan inte nås via en klassinstans, utan bara via en instans av gränssnittet. Dessutom kan standardgränssnittsmedlemmar endast nås via en instans av gränssnittet.

Mer information om explicit gränssnittsimplementering finns i Explicit gränssnittsimplementering.

Exempel på gränssnittsimplementering

I följande exempel visas gränssnittsimplementering. I det här exemplet innehåller gränssnittet egenskapsdeklarationen och klassen innehåller implementeringen. Alla instanser av en klass som implementerar har heltalsegenskaper IPointx och y.

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

Språkspecifikation för C#

Mer information finns i avsnittet Gränssnitt i C#-språkspecifikationen, funktionsspecifikationen för C# 8 – Standardgränssnittsmedlemmar och funktionsspecifikationen för C# 11 – statiska abstrakta medlemmar i gränssnitt

Se även