Codectionary / Developer documentation / C#

Interfaces

An interface defines a contract of members that implementing classes must provide, without specifying how those members work internally. By convention, interface names start with a capital I (IShape, IComparable). Unlike a class, an interface cannot be instantiated directly. A class uses a colon to implement an interface, and a single class can implement multiple interfaces - C#'s way of achieving a form of multiple inheritance.

Syntax

interface IInterfaceName {\n  returnType MethodName(parameters);\n}

Examples

Basic Interface

Defining a contract and implementing it in a class.

public interface IShape
{
    double Area();
    double Perimeter();
}

public class Rectangle : IShape
{
    public double Width, Height;

    public Rectangle(double width, double height)
    {
        Width = width;
        Height = height;
    }

    public double Area() => Width * Height;
    public double Perimeter() => 2 * (Width + Height);
}

IShape rect = new Rectangle(5, 3);
Console.WriteLine(rect.Area());  // 15

Implementing Multiple Interfaces

A class can implement more than one interface, gaining the contract of each.

public interface ISwimmer { void Swim(); }
public interface IRunner { void Run(); }

public class Triathlete : ISwimmer, IRunner
{
    public void Swim() => Console.WriteLine("Swimming");
    public void Run() => Console.WriteLine("Running");
}

Triathlete athlete = new Triathlete();
athlete.Swim();
athlete.Run();

Default Interface Methods (C# 8+)

Modern C# lets interfaces provide a default implementation, which implementing classes can use as-is or override.

public interface IVehicle
{
    void Drive();

    void Honk() => Console.WriteLine("Beep beep!");  // has a body
}

public class Car : IVehicle
{
    public void Drive() => Console.WriteLine("Driving a car");
}

Car car = new Car();
car.Drive();
((IVehicle)car).Honk();  // uses the default implementation

Interface as a Type Reference

Using an interface as the declared type lets you write flexible code that works with any implementation.

public interface IPaymentMethod
{
    void Pay(double amount);
}

public class CreditCard : IPaymentMethod
{
    public void Pay(double amount) => Console.WriteLine($"Paid ${amount} with credit card");
}

public class PayPal : IPaymentMethod
{
    public void Pay(double amount) => Console.WriteLine($"Paid ${amount} with PayPal");
}

void ProcessPayment(IPaymentMethod method, double amount) => method.Pay(amount);

ProcessPayment(new CreditCard(), 50.0);
ProcessPayment(new PayPal(), 30.0);

Best practices

  • Program to an interface rather than a concrete class (declare variables as IShape, not Rectangle) for more flexible, decoupled code
  • Prefix interface names with I (IShape, IRepository) following standard C# naming conventions
  • Keep interfaces small and focused (Interface Segregation Principle) - many specific interfaces beat one large, do-everything interface
  • Use default interface methods sparingly, mainly for adding new functionality to an interface without breaking existing implementing classes

At a glance

Purpose
Applications on the .NET platform
File extension
.cs
Runs in
.NET runtime
Usually used with
.NET SDK and libraries

Specifications & further reading

Related C# documentation

Classes & Objects
A class is a blueprint for creating objects, bundling related data (fields/properties) and behavior (methods) together. C# is a fully object-oriented language - every application has at least one class, typically with a Main method as its entry point. An object is a specific instance of a class, created with the new keyword, with its own independent copy of the class's instance data.
Constructors
A constructor is a special method that runs automatically when an object is created with new, used to initialize the object's state. A constructor shares its name with the class and has no return type. C# supports constructor overloading (multiple constructors with different parameter lists) and constructor chaining with this(...), where one constructor calls another in the same class to avoid duplicating initialization logic.
Properties (get/set)
Properties are C#'s idiomatic way to expose class data through accessor-like syntax while still allowing controlled access via get and set. Unlike a plain public field, a property can validate a value before it's set, compute a value on the fly, or restrict access to read-only. Auto-implemented properties (using { get; set; } with no body) provide a concise shorthand when no custom logic is needed.
Access Modifiers
Access modifiers control the visibility of classes, fields, methods, and properties from other parts of a program. C# provides public (accessible from anywhere), private (accessible only within the declaring class - the default for class members), protected (accessible within the class and its subclasses), internal (accessible only within the same assembly/project), and combinations like protected internal and private protected.