In which cases and for what purposes do we use interfaces in C#?
sobes.tech AI
Answer from AI
Interfaces in C# are used for the following purposes:
-
Defining a contract: An interface defines a set of members (methods, properties, events, indexers) that a class or struct implementing this interface must implement. This ensures uniformity in the behavior of different types.
// Interface definition public interface IDrawable { void Draw(); int LineThickness { get; set; } } // Class implementing the interface public class Circle : IDrawable { public int LineThickness { get; set; } public void Draw() { // Logic for drawing a circle } } -
Polymorphism: Using interfaces allows working with objects of different types through a common interface type. This is achieved because any reference to an object implementing an interface can be cast to that interface type.
// Method working with any object implementing IDrawable public void Render(IDrawable item) { item.Draw(); // Calls the specific implementation of Draw } // Usage: IDrawable circle = new Circle(); Render(circle); // Will call the Draw() implementation from the Circle class -
Multiple Inheritance: C# does not support multiple class inheritance, but allows a class or struct to implement multiple interfaces. This enables a type to have behaviors defined in different "contracts".
public interface ISaveable { void Save(); } public interface ILoadable { void Load(); } // Class implementing multiple interfaces public class ConfigurationManager : ISaveable, ILoadable { public void Save() { // Save logic } public void Load() { // Load logic } } -
Loose Coupling: Using interfaces reduces dependencies between components. Instead of depending on a specific class, a component can depend on an interface. This facilitates replacing implementations and testing.
public interface ILogger { void LogMessage(string message); } public class FileLogger : ILogger { public void LogMessage(string message) { // File writing logic } } public class DatabaseLogger : ILogger { public void LogMessage(string message) { // Database writing logic } } public class ProcessingEngine { private readonly ILogger _logger; // Dependency on interface, not on a specific implementation public ProcessingEngine(ILogger logger) { _logger = logger; } public void ProcessData() { // ... _logger.LogMessage("Data processed."); } } -
Extensibility: Interfaces make it easy to add new implementations of existing behaviors without changing the code that uses this interface.
-
Documentation and self-documentation: A well-named interface with comments on its members serves as a form of documentation, describing what behavior is expected from objects implementing this interface.