interface (C# referencia)

Az interfész egy szerződést határoz meg. Bármely class, record vagy struct a szerződést megvalósítónak biztosítania kell a felületen meghatározott tagok megvalósítását. Egy felület meghatározhat egy alapértelmezett implementációt a tagok számára. Tagokat is meghatározhat static annak érdekében, hogy egységes implementációt biztosítson a közös funkciókhoz. A C# 11-től kezdődően a felület definiálhatja static abstract vagy static virtual a tagok deklarálhatják, hogy egy implementálási típusnak meg kell adnia a deklarált tagokat. A metódusok általában azt deklarálják, static virtual hogy egy implementációnak túlterhelt operátorokat kell meghatároznia.

Az alábbi példában az osztálynak ImplementationClass olyan metódust SampleMethod kell implementálnia, amely nem tartalmaz paramétereket, és visszaadja azokat void.

További információkért és példákért lásd : Interfészek.

Példa felület

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

Egy felület tagja lehet egy névtérnek vagy egy osztálynak. A felületi deklarációk a következő tagok nyilatkozatait (implementálás nélküli aláírásokat) tartalmazhatnak:

Alapértelmezett illesztőtagok

Ezek a korábbi tagdeklarációk általában nem tartalmaznak törzset. A felület tagja deklarálhat egy törzset. Az interfész tagszervezetei az alapértelmezett implementációk. A testületekkel rendelkező tagok lehetővé teszik, hogy az interfész "alapértelmezett" implementációt biztosítson az olyan osztályok és szerkezetek számára, amelyek nem biztosítanak felülíró megvalósítást. A felület a következőket tartalmazhatja:

Statikus absztrakt és virtuális tagok

A C# 11-től kezdődően egy felület a mezők kivételével minden tagtípushoz deklarálhat static abstract és static virtual tagokat. Az interfészek deklarálhatják, hogy a implementálási típusoknak operátorokat vagy más statikus tagokat kell meghatározniuk. Ez a funkció lehetővé teszi, hogy az általános algoritmusok számszerű viselkedést adjanak meg. A .NET-futtatókörnyezetben a numerikus típusok példái láthatók, például System.Numerics.INumber<TSelf>. Ezek az interfészek olyan gyakori matematikai operátorokat határoznak meg, amelyeket számos numerikus típus implementál. A fordítónak fordításkor meg kell oldania a static virtual hívásokat és static abstract a metódusokat. Az static virtual illesztőkben deklarált metódusok és static abstract metódusok nem rendelkeznek az osztályokban deklarált vagy abstract azokhoz hasonló futtatókörnyezeti küldési virtual mechanizmussal. Ehelyett a fordító a fordításkor elérhető típusinformációkat használja. Ezért a static virtual módszerek szinte kizárólag általános felületeken vannak deklarálva. Ezenkívül a legtöbb deklarált interfésznek vagy static abstract metódusnak azt kell deklarálniastatic virtual, hogy az egyik típusparaméternek implementálnia kell a deklarált interfészt. Az interfész például azt deklarálja, INumber<T> hogy T implementálnia INumber<T>kell. A fordító a típusargumentum használatával oldja fel a felületi deklarációban deklarált metódusok és operátorok hívásait. A típus például implementálja a int következőt INumber<int>: . Amikor a típusparaméter T a típusargumentumot intjelöli, a rendszer meghívja a static deklarált int tagokat. Másik lehetőségként, ha double a típus argumentumot adja meg, a rendszer meghívja a staticdouble típuson deklarált tagokat.

Fontos

A metódusküldés static abstract és static virtual a felületeken deklarált metódusok feloldása egy kifejezés fordítási időtípusával történik. Ha egy kifejezés futásidejű típusa egy másik fordítási időtípusból származik, a rendszer meghívja az alap (fordítási idő) típus statikus metódusait.

Ezt a funkciót úgy is kipróbálhatja, ha a felületi statikus absztrakt tagokról szóló oktatóanyagot használja.

Interfész öröklése

Előfordulhat, hogy az interfészek nem tartalmaznak példányállapotot. Bár a statikus mezők most már engedélyezettek, a példánymezők nem engedélyezettek a felületeken. A példány automatikus tulajdonságai nem támogatottak az interfészekben, mivel implicit módon deklarálnának egy rejtett mezőt. Ez a szabály enyhe hatással van a tulajdonságdeklarációkra. A felületi deklarációkban az alábbi kód nem deklarál automatikusan implementált tulajdonságot, ahogyan az egy class vagy struct. Ehelyett egy olyan tulajdonságot deklarál, amely nem rendelkezik alapértelmezett implementációval, de az interfészt megvalósító bármilyen típusban implementálni kell:

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

Egy interfész egy vagy több alapillesztőtől örökölhet. Ha egy felület felülír egy alapillesztőben implementált metódust, az explicit felület implementálási szintaxisát kell használnia.

Ha egy alaptípuslista alaposztályt és interfészeket tartalmaz, az alaposztálynak a listában kell elsőnek lennie.

Az interfészt megvalósító osztály explicit módon implementálhatja az adott felület tagjait. Egy explicit módon implementált tag nem érhető el osztálypéldányon keresztül, csak a felület egy példányán keresztül. Emellett az alapértelmezett illesztőtagok csak a felület egy példányán keresztül érhetők el.

További információ az explicit felület implementálásáról: Explicit Interface Implementáció.

Példa felület implementálására

Az alábbi példa a felület implementálását mutatja be. Ebben a példában a felület tartalmazza a tulajdonságdeklarációt, az osztály pedig a megvalósítást. A megvalósító IPoint osztály minden példánya egész számtulajdonságokkal x és 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

C# nyelvspecifikáció

További információkért tekintse meg a C# nyelvi specifikáció Felületek szakaszát, a C# 8 – Alapértelmezett felülettagok funkcióspecifikációját, valamint a C# 11 – statikus absztrakt tagok funkciós specifikációját az interfészekben

Lásd még