Interface vs abstract class in C#
Use an interface to describe a capability that unrelated types can share. Use an abstract class when the types are genuinely related and you want to share implementation.
public interface IExportable
{
string ToCsv();
}
public abstract class Lesson
{
public string Title { get; init; } = "";
public abstract int DurationSeconds { get; }
public string Formatted() =>
$"{DurationSeconds / 60}:{DurationSeconds % 60:D2}"; // shared logic
}#The decisive difference
A class can implement many interfaces but inherit from one base class. So an interface is the right choice for a capability that cuts across unrelated types — IDisposable, IComparable, IEnumerable.
#Ask "is-a" or "can-do"
- A
VideoLessonis aLesson→ abstract class. - A
VideoLessoncan be exported → interface.
#Interfaces can have default implementations now
Since C# 8:
public interface ILogger
{
void Log(string message);
void LogError(string message) => Log($"ERROR: {message}");
}This lets you add a method to a published interface without breaking implementers. It does not make interfaces a replacement for abstract classes — interfaces still cannot hold state.
#Prefer interfaces for testability
public class VideoService
{
private readonly IRepository _repo;
public VideoService(IRepository repo) => _repo = repo;
}Depending on an interface means a test can pass a fake. Depending on a concrete class means the test needs a real database.
#Do not over-abstract
An interface with exactly one implementation, created "for flexibility", is usually just an extra file. Add it when you have a second implementation or a test that needs one.