PY
C#

Python to C#

10 lessons

Progress0%
1Variables & Types2Classes & OOP3Collections & LINQ4Async/Await5Exception Handling6File I/O7Generics8Delegates and Events9Records and Pattern Matching10Interfaces
All Mirror Courses
PY
C#
Interfaces
MirrorLesson 10 of 10
Lesson 10

Interfaces

C# interfaces vs Python protocols and ABCs

Introduction

In this lesson, you'll learn about interfaces in C#. Coming from Python, you already have a foundation for understanding this concept. We'll build on that knowledge while highlighting the key differences.

Mirror Card
PY
From Python:

In Python, you're familiar with c# interfaces vs python protocols and abcs.

C#
In C#:

C# has its own approach to c# interfaces vs python protocols and abcs, which we'll explore step by step.

The C# Way

Let's see how C# handles this concept. Here's a typical example:

C#
C# Example
// Interface: contract only (or with default implementations)
public interface IDrawable
{
    void Draw();
    double Area();

    // Default method (C# 8+) — like Python concrete method in ABC
    string Describe() => $"Area: {Area()}";
}

// Explicit implementation
public class Circle : IDrawable
{
    public double Radius { get; }
    Circle(double r) => Radius = r;

    public void Draw() => Console.WriteLine("O");
    public double Area() => Math.PI * Radius * Radius;
}

// Multiple interfaces
public class Ring : IDrawable, IComparable<Ring>
{
    public void Draw() { }
    public double Area() { return 0; }
    public int CompareTo(Ring? other) { return 0; }
}

// Explicit interface implementation (avoids name clashes)
public class Widget : IFoo, IBar
{
    void IFoo.DoThing() { }  // only accessible via IFoo reference
    void IBar.DoThing() { }
}

// Polymorphism via interface type
void Render(IDrawable d) => d.Draw();
Render(new Circle(5));

Comparing to Python

Here's how you might have written similar code in Python:

PY
Python (What you know)
from typing import Protocol
from abc import ABC, abstractmethod

# Protocol (structural — like Go interfaces)
class Drawable(Protocol):
    def draw(self) -> None: ...
    def area(self) -> float: ...

# Any class with draw() + area() satisfies Drawable
class Circle:
    def draw(self) -> None: print("O")
    def area(self) -> float: return 3.14 * self.r ** 2

# Abstract base class (nominal — must inherit)
class Shape(ABC):
    @abstractmethod
    def area(self) -> float: ...

    def describe(self) -> str:     # concrete default
        return f"Area: {self.area()}"

class Rectangle(Shape):
    def area(self) -> float: return self.w * self.h

# Can't mix — Protocol is structural, ABC is nominal
def render(d: Drawable) -> None:
    d.draw()
Mirror Card
PY
From Python:

You may be used to different syntax or behavior.

C#
In C#:

C# interfaces are nominal — classes must explicitly state 'implements IXxx'

Mirror Card
PY
From Python:

You may be used to different syntax or behavior.

C#
In C#:

Python Protocols are structural (duck typing); ABCs are nominal like C# interfaces

Mirror Card
PY
From Python:

You may be used to different syntax or behavior.

C#
In C#:

Default interface methods (C# 8+) allow adding methods without breaking implementations

Mirror Card
PY
From Python:

You may be used to different syntax or behavior.

C#
In C#:

A C# class can implement multiple interfaces (no multiple class inheritance)

Mirror Card
PY
From Python:

You may be used to different syntax or behavior.

C#
In C#:

Explicit interface implementation resolves method name conflicts between interfaces

Step-by-Step Breakdown

1. Declare and Implement

C# interfaces define method/property signatures. Unlike Python Protocol, implementing classes must explicitly declare the interface.

PY
Python
class Drawable(Protocol):
    def draw(self) -> None: ...

class Circle:  # implicitly satisfies
C#
C#
interface IDrawable { void Draw(); }
class Circle : IDrawable  // explicit
{
    public void Draw() => Console.WriteLine("O");
}

2. Multiple Interfaces

A class can implement multiple interfaces separated by commas. This is C#'s way to achieve multiple inheritance of behavior.

PY
Python
class Shape(Drawable, Serializable): ...  # multiple base
C#
C#
class Shape : IDrawable, ISerializable
{
    public void Draw() { }
    public void Serialize(Stream s) { }
}

3. Default Methods

C# 8+ allows default method bodies in interfaces, like Python's concrete methods in ABC. Implementing classes can override them.

PY
Python
class Shape(ABC):
    def describe(self): return f"Area:{self.area()}"
C#
C#
interface IShape {
    double Area();
    string Describe() => $"Area: {Area()}"; // default
}

4. Interface as Type

Program to interfaces, not concrete types. Assign any implementing class to an interface variable — enables polymorphism and testability.

PY
Python
def process(shape: Drawable) -> None:
    shape.draw()
C#
C#
void Process(IDrawable d) => d.Draw();
// Anywhere:
IDrawable d = new Circle(5);
d = new Rectangle(3, 4); // can reassign
Rule of Thumb
Accept interface types in function parameters, return concrete types from factories.

Common Mistakes

When coming from Python, developers often make these mistakes:

  • C# interfaces are nominal — classes must explicitly state 'implements IXxx'
  • Python Protocols are structural (duck typing); ABCs are nominal like C# interfaces
  • Default interface methods (C# 8+) allow adding methods without breaking implementations
Common Pitfall
Don't assume C# works exactly like Python. While the concepts may be similar, the syntax and behavior can differ significantly.

Key Takeaways

  • C# interfaces are nominal — explicit 'implements'; Python Protocols are structural
  • A class can implement multiple interfaces — C#'s multiple inheritance mechanism
  • Default methods (C# 8+) add concrete implementations to interfaces
  • Program to interfaces: accept IDrawable, not Circle — enables polymorphism and easy testing
Rule of Thumb
The best way to learn is by doing. Try rewriting some of your Python code in C# to practice these concepts.
PreviousFinish