C# Interface

If you wonder how to structure your C# code for maximum reusability and flexibility, then understanding the C# Interface is key. So, let"s get started learning Interface in C#.

KEY TAKEAWAYS:

  1. C# Interface defines a contract for classes to adhere to.
  2. When a class implements a C# interface then it must have to provide implementations for all the members of the interface.
  3. Interface in C# can include properties, which are declared similarly to properties in classes but without implementation.
  4. Abstract classes contain both definitions and implementations, while interfaces only contain definitions.
  5. C# Interfaces enable code modularity, loose coupling, and multiple inheritances in C#.

C# Interface

An Interface in C# is a reference type that contains only abstract members like methods, properties, events, or indexers. It's a blueprint for a class and acts like a contract, ensuring all classes that implement the interface adhere to the same structure. Interfaces enhance software's modularity and extensibility by enabling multiple inheritance, which C# doesn't support directly.

Here is a simple example of Interface in C#:

public interface IAnimal
{
    void Speak();
}

Purpose of Interface in C#

The primary goal of an interface is to ensure that certain classes contain particular methods, properties, events, or indexers. They promote code reuse and design by contract, which helps maintain a clean and consistent architecture.

C# Implement Interface

Implementing an interface in C# is straightforward.When a class going to implement an interface, it must provide an implementation for all the members defined by the interface. Here we will implement an interface c#.

public class Dog : IAnimal
{
    public void Speak()
    {
        Console.WriteLine("Woof Woof");
    }
}

In this case, the "Dog" class implements the "IAnimal" interface and provides an implementation for the "Speak" method.

C# Interface Property

An interface can also contain properties. These properties are declared in the same way as in a class but without any implementation. Have a look at the C# property in Interface.

public interface IAnimal
{
    string Name { get; set; }
    
    void Speak();
}

The class implementing the interface must then provide the implementation for these properties:

public class Dog : IAnimal
{
    public string Name { get; set; }

    public void Speak()
    {
        Console.WriteLine("Woof Woof");
    }
}

C# Abstract Class vs Interface

An abstract class in C# shares similarities with interfaces C#, but they serve different purposes. An abstract class can contain both definitions and implementations, while interfaces only contain definitions. Furthermore, a class can only inherit from one abstract class, but it has the ability to implement multiple interfaces. Deciding between Abstract Class and Interface often depends on the specific design requirements of your application.

C# Interface Default Implementation

C# 8.0 introduced default interface methods, allowing us to add methods to an interface that include an implementation. This feature can help when we need to extend an interface without breaking existing implementations:

public interface IAnimal
{
    void Speak();

    // Default implementation
    void Eat()
    {
        Console.WriteLine("Eating");
    }

}

In this case, any class implementing the "IAnimal" interface can choose to override the "Eat" method, but if they don't, the default implementation will be used.

C# Interface Static Method

Starting with C# 8.0, interfaces can contain static methods. These methods belong to the interface itself rather than any instance of the interface:

public interface IAnimal
{
    static void DisplayType()
    {
        Console.WriteLine("Animal");
    }
}

This method can be called directly:

IAnimal.DisplayType(); // Outputs: Animal

C# Using Interfaces

Interfaces play a crucial role in ensuring robustness and flexibility in C# programming. They support the development of extensible and testable code by enabling dependency injection and promoting the SOLID principles, particularly the Dependency Inversion Principle and the Interface Segregation Principle. Here are some key benefits:

  1. They enable loosely-coupled code, making the code more modular and easier to test.
  2. They provide a way to achieve multiple inheritances in C#.
  3. They allow for dependency injection and mocking in unit tests.

For example, consider this interface and its implementation:

public interface IDatabase
{
    void Connect();
    void Disconnect();
}

public class SqlDatabase : IDatabase
{
    public void Connect()
    {
        Console.WriteLine("Connecting to SQL Database...");
    }

    public void Disconnect()
    {
        Console.WriteLine("Disconnecting from SQL Database...");
    }
}

public class Application
{
    private IDatabase _database;
    
    public Application(IDatabase database)
    {
        _database = database;
    }
    
    public void Start()
    {
        _database.Connect();
    }
    
    public void Stop()
    {
        _database.Disconnect();
    }
}

In the example above, the "Application" class depends on the "IDatabase" interface, not a specific database. This design makes it easy to switch to a different database or mock the database in unit tests.

C# Interface Example

Let"s see more real-life Interface with example in C#.

Inheritance And Interface In C#:

An interface can inherit from another interface, following is a complete C# console example:

using System;

public interface IEat
{
    void Eat();
}

public interface IAnimal : IEat
{
    void Speak();
}

public class Dog : IAnimal
{
    public void Eat()
    {
        Console.WriteLine("Dog is eating.");
    }

    public void Speak()
    {
        Console.WriteLine("Dog says woof!");
    }
}

public class Cat : IAnimal
{
    public void Eat()
    {
        Console.WriteLine("Cat is eating.");
    }

    public void Speak()
    {
        Console.WriteLine("Cat says meow!");
    }
}

public class Program
{
    static void Main(string[] args)
    {
        IAnimal dog = new Dog();
        dog.Eat();
        dog.Speak();

        IAnimal cat = new Cat();
        cat.Eat();
        cat.Speak();
    }
}

Explicit Interface Implementation C#:

You might want to use explicit implementation when you want to hide interface members from being directly accessible through class instances.

    interface IInterfaceA
    {
        void SomeMethod();
    }

    class MyClass : IInterfaceA
    {
        void IInterfaceA.SomeMethod()
        {
        }
    }

C# Implement Multiple Interfaces:

A class can implement multiple interfaces:

    interface IInterfaceA
    {
        void MethodA();
    }

    interface IInterfaceB
    {
        void MethodB();
    }

    class MyClass : IInterfaceA, IInterfaceB
    {
        public void MethodA() {}
        public void MethodB() {}
    }

Example of Interface in C# - To Create Pluggable Software Components:

    interface ILogger
    {
        void Log(string message);
    }

    class ConsoleLogger : ILogger
    {
        public void Log(string message)
        {
            Console.WriteLine(message);
        }
    }

    class FileLogger : ILogger
    {
        public void Log(string message)
        {
            // Implement file logging here
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            ILogger logger = new ConsoleLogger();  // Can easily be switched to FileLogger object by changing the instantiation.
            logger.Log("Hello, World!");
        }
    }

Dependency Injection C# Interface:

using System;

interface ILogger
{
    void Log(string message);
}

interface ICustomerService
{
    void SaveCustomer(string name);
}

class CustomerService : ICustomerService
{
    private readonly ILogger _logger;

    public CustomerService(ILogger logger)
    {
        _logger = logger;
    }

    public void SaveCustomer(string name)
    {
        _logger.Log($"Saving customer {name}");
        // Save the customer
    }
}

class ConsoleLogger : ILogger
{
    public void Log(string message)
    {
        Console.WriteLine(message);
    }
}

class Program
{
    static void Main(string[] args)
    {
        ILogger logger = new ConsoleLogger();
        ICustomerService customerService = new CustomerService(logger);

        customerService.SaveCustomer("John Doe");
    }
}

Events In Interface C#:

using System;

public class MyEventArgs : EventArgs
{
    public string Message { get; set; }
}

public interface IMyEventHandler
{
    event EventHandler<MyEventArgs> OnEvent;
}

public class MyEventHandler : IMyEventHandler
{
    public event EventHandler<MyEventArgs> OnEvent;

    public void TriggerEvent(MyEventArgs args)
    {
        OnEvent?.Invoke(this, args);
    }
}

public class Program
{
    public static void Main(string[] args)
    {
        MyEventHandler handler = new MyEventHandler();
        handler.OnEvent += Handler_OnEvent;

        Console.WriteLine("Enter a message:");
        string message = Console.ReadLine();

        MyEventArgs eventArgs = new MyEventArgs { Message = message };
        handler.TriggerEvent(eventArgs);

        Console.ReadLine();
    }

    private static void Handler_OnEvent(object sender, MyEventArgs e)
    {
        Console.WriteLine("Event triggered with message: " + e.Message);
    }
}

C# Generics With Interface:

using System;
using System.Collections.Generic;

public interface IRepository<T>
{
    T GetById(int id);
    IEnumerable<T> GetAll();
    void Save(T entity);
    void Delete(T entity);
}

public class User
{
    public int Id { get; set; }
    public string Name { get; set; }
}

public class UserRepository : IRepository<User>
{
    private List<User> users;

    public UserRepository()
    {
        users = new List<User>();
    }

    public User GetById(int id)
    {
        return users.Find(user => user.Id == id);
    }

    public IEnumerable<User> GetAll()
    {
        return users;
    }

    public void Save(User entity)
    {
        users.Add(entity);
        Console.WriteLine("User saved: " + entity.Name);
    }

    public void Delete(User entity)
    {
        users.Remove(entity);
        Console.WriteLine("User deleted: " + entity.Name);
    }
}

public class Program
{
    public static void Main(string[] args)
    {
        IRepository<User> userRepository = new UserRepository();

        User user1 = new User { Id = 1, Name = "John" };
        User user2 = new User { Id = 2, Name = "Jane" };

        userRepository.Save(user1);
        userRepository.Save(user2);

        Console.WriteLine("Users:");
        foreach (User user in userRepository.GetAll())
        {
            Console.WriteLine("Id: " + user.Id + ", Name: " + user.Name);
        }

        User retrievedUser = userRepository.GetById(1);
        if (retrievedUser != null)
        {
            Console.WriteLine("Retrieved user: Id: " + retrievedUser.Id + ", Name: " + retrievedUser.Name);
        }
        else
        {
            Console.WriteLine("User with Id 1 not found.");
        }

        userRepository.Delete(user2);

        Console.ReadLine();
    }
}

Benefits Of Interface In C#

The benefits of using interface in C# include achieving polymorphism, separating implementation details from the interface definition, and making your code more modular and easier to maintain. C# Interfaces also allow you to define a contract that other classes must adhere to, which can help to make sure that your code is more reliable and easier to test.

Final Words for C# Interfaces

Interfaces in C# are powerful tool for creating flexible, extensible, and testable code. Understanding interfaces and knowing when to use them is an essential skill for any C# programmer. Remember, an interface defines a contract for classes, and by using them, you can design more maintainable and scalable applications. Whether it"s implementing multiple behaviors with multiple interfaces, defining properties, or utilizing default and static methods, interfaces bring a lot of benefits to your C# programming toolbox. Hopefully, the example of Interface in C#, which we have covered, will help you a lot. Happy coding!

Accept our invitation to read our other fantastic articles on C# Interfaces. You will learn a lot! Interface C#, C# Abstract Class Vs Interface, Difference between Abstract Class and Interface in C#.