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:
- Konstanter
- Operatorer
- Statisk konstruktor.
- Kapslade typer
- Statiska fält, metoder, egenskaper, indexerare och händelser
- Medlemsdeklarationer med den explicita syntaxen för gränssnittsimplementering.
- Explicita åtkomstmodifierare (standardåtkomsten är
public
).
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 int
anropas 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 IPoint
x
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
Feedback
https://aka.ms/ContentUserFeedback.
Kommer snart: Under hela 2024 kommer vi att fasa ut GitHub-problem som feedbackmekanism för innehåll och ersätta det med ett nytt feedbacksystem. Mer information finns i:Skicka och visa feedback för