Редагувати

Поділитися через


interface (C# Reference)

An interface defines a contract. Any class, record or struct that implements that contract must provide an implementation of the members defined in the interface. An interface may define a default implementation for members. It may also define static members in order to provide a single implementation for common functionality. Beginning with C# 11, an interface may define static abstract or static virtual members to declare that an implementing type must provide the declared members. Typically, static virtual methods declare that an implementation must define a set of overloaded operators.

In the following example, class ImplementationClass must implement a method named SampleMethod that has no parameters and returns void.

For more information and examples, see Interfaces.

A top-level interface, one declared in a namespace but not nested inside another type, can be declared public or internal. The default is internal. Nested interface declarations, those declared inside another type, can be declared using any access modifier.

Interface members without an implementation can't include an access modifier. Members with a default implementation can include any access modifier.

Example interface

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

An interface can be a member of a namespace or a class. An interface declaration can contain declarations (signatures without any implementation) of the following members:

Default interface members

These preceding member declarations typically don't contain a body. An interface member may declare a body. Member bodies in an interface are the default implementation. Members with bodies permit the interface to provide a "default" implementation for classes and structs that don't provide an overriding implementation.

Important

Adding default interfaces members forces any ref struct that implements the interface to add an explicit declaration of that member.

An interface may include:

Static abstract and virtual members

Beginning with C# 11, an interface may declare static abstract and static virtual members for all member types except fields. Interfaces can declare that implementing types must define operators or other static members. This feature enables generic algorithms to specify number-like behavior. You can see examples in the numeric types in the .NET runtime, such as System.Numerics.INumber<TSelf>. These interfaces define common mathematical operators that are implemented by many numeric types. The compiler must resolve calls to static virtual and static abstract methods at compile time. The static virtual and static abstract methods declared in interfaces don't have a runtime dispatch mechanism analogous to virtual or abstract methods declared in classes. Instead, the compiler uses type information available at compile time. Therefore, static virtual methods are almost exclusively declared in generic interfaces. Furthermore, most interfaces that declare static virtual or static abstract methods declare that one of the type parameters must implement the declared interface. For example, the INumber<T> interface declares that T must implement INumber<T>. The compiler uses the type argument to resolve calls to the methods and operators declared in the interface declaration. For example, the int type implements INumber<int>. When the type parameter T denotes the type argument int, the static members declared on int are invoked. Alternatively, when double is the type argument, the static members declared on the double type are invoked.

Important

Method dispatch for static abstract and static virtual methods declared in interfaces is resolved using the compile time type of an expression. If the runtime type of an expression is derived from a different compile time type, the static methods on the base (compile time) type will be called.

You can try this feature by working with the tutorial on static abstract members in interfaces.

Interface inheritance

Interfaces may not contain instance state. While static fields are now permitted, instance fields aren't permitted in interfaces. Instance auto-properties aren't supported in interfaces, as they would implicitly declare a hidden field. This rule has a subtle effect on property declarations. In an interface declaration, the following code doesn't declare an automatically implemented property as it does in a class or struct. Instead, it declares a property that doesn't have a default implementation but must be implemented in any type that implements the interface:

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

An interface can inherit from one or more base interfaces. When an interface inherits from another interface, a type implementing the derived interface must implement all the members in the base interfaces as well as those declared in the derived interface, as shown in the following 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() { }
}

When an interface overrides a method implemented in a base interface, it must use the explicit interface implementation syntax.

When a base type list contains a base class and interfaces, the base class must come first in the list.

A class that implements an interface can explicitly implement members of that interface. An explicitly implemented member can't be accessed through a class instance, but only through an instance of the interface. In addition, default interface members can only be accessed through an instance of the interface.

For more information about explicit interface implementation, see Explicit Interface Implementation.

Example interface implementation

The following example demonstrates interface implementation. In this example, the interface contains the property declaration and the class contains the implementation. Any instance of a class that implements IPoint has integer properties x and 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# language specification

For more information, see the Interfaces section of the C# language specification, the feature specification for C# 8 - Default interface members, and the feature spec for C# 11 - static abstract members in interfaces

See also