Understanding Interfaces

Kmcnet 1,066 Reputation points
2024-08-01T22:24:40.6033333+00:00

Hello everyone and thanks for the help in advance. This is probably a stupid question, but I really can't understand the concept of an interface and when to use it as opposed to using a class. For example, it appears many interfaces are used for data access, for example IEmployees, but why is this different than using a class called Employees that has a get, edit and update function. Any help would be appreciated.

Developer technologies ASP.NET ASP.NET Core
Developer technologies C#
0 comments No comments
{count} votes

Accepted answer
  1. Anonymous
    2024-08-02T04:48:28.3333333+00:00

    Hi Kmcnet, please allow me to share a common scenario with you to help you understand how interface helps us.

    Normally, we have interfaces and corresponding services, and we could use dependency injection to inject it in Program.cs then we can use the methods defined in services. By the way, we always create service for CRUD operations.

    Let's assume we have a user table in the MySql database, and we used EF core to do CRUD operations on this user table, so that we create a UserService and IUserService for manage this table. And one day we have a requirement that we need to use Sql Server database instead, let's assume that the queries in MySql and Sql Server are different so that we need to write different EF core codes to do the query. Then we only need to create a new UserServiceForSqlServer class, and write the same method name as what we have in the origin UserService. The rest are changing the DI injection in Program.cs and other Controllers or Services use this UserService, we don't need to change any other codes.

    It's a common business scenario. For example, we have an application for company A which only uses MySql and if we want to make our application to be capable for company B which only uses Sql Server, it's good idea to write 2 version CRUD operations. Since the rest part of the codes are the same, we can get benefit from defining an interface but with 2 implementations, we only need to change the DI configuration.

    This is what interface helps us. Interface only define abstract method name but doesn't provide implementation. Therefore, in Controllers we only need to know what kind of method we need to call and call the corresponding Interface methods. We can recognize interface methods are defined for different requirements, such as operate table A, collect data B. The implementation might be changed in future, but the requirements might not be changed. Through the design for Interface, we can get benefit from loose coupling.

    It's a good habit for us to write an interface for services which services themselves might be commonly used but shall be high probably changed, interface seems to play the role as entrance, no matter how the services change, when the result type doesn't change, we can use interface so that the part calling the service doesn't need to be changed. Certainly there're some other benefits interface bringing to us, I just show you a common scenario.


    If the answer is the right solution, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment".

    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.

    Best regards,

    Tiny

    0 comments No comments

6 additional answers

Sort by: Most helpful
  1. Igor Korot 56 Reputation points
    2024-08-01T22:59:39.54+00:00

    Hi,

    Interface is just a fancy name for a class that cannot be instantiated.

    Think of it as follows:

    Leta say you have a class called Animal

    And then you have a class called Dog and a class called Wolf which are derived from the class Animal.

    Now your program don't care about class Animal and how many actual children the Animal class.

    But in reality the Animal class defines the interface for the 2 classes your program is interested in.

    0 comments No comments

  2. SurferOnWww 4,631 Reputation points
    2024-08-02T01:31:14.9633333+00:00

    I really can't understand the concept of an interface

    Please see the following document:

    Interfaces

    "An interface defines a contract. A class or struct that implements an interface shall adhere to its contract."

    when to use it as opposed to using a class.

    A good example, in my opinion, is IDisposable Interface.

    If a class has unmanaged resources which must be disposed, such class should inherit IDisposable interface and include the Dispose method as shown in the sample code in IDisposable Interface.

    A programmer will be able to know that the class which inherits the IDisposable interface has unmanaged resources which must be disposed after use such like:

    public static void Main()
    {
       // Insert code here to create
        using (var myResource = new MyResource())
        {
            // and use the MyResource object.
        }
    }
    
    0 comments No comments

  3. Udaiappa Ramachandran 726 Reputation points MVP
    2024-08-02T02:24:55.6433333+00:00

    Use an interface in C# to define a contract that multiple classes can implement for shared capabilities, while a class should be used to describe the implementation of specific behaviors and states, allowing for inheritance and encapsulation.User's image

    User's image

    User's image User's image

    0 comments No comments

  4. Karen Payne MVP 35,586 Reputation points Volunteer Moderator
    2024-08-02T11:45:13.93+00:00

    There are many usages for interfaces. The following uses the following interface which when a class uses it the class must implement, in this case the properties of the interface. Below the interface are two classes that implement the interface.

    Example1

    Points of interest

    • We can determine employee from manager
    • Although both have a primary key which are the same in both classes a business rule indicates they must use Id so below Id points to Identifier.
    public interface IEmployee
    {
        public int Id { get; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
    }
    public class Employee : IEmployee
    {
        public int Identifier { get; set; }
        public int Id => Identifier;
        public string FirstName { get; set; }
        public string LastName { get; set; }
    }
    public class Manager : IEmployee
    {
        public int Identifier { get; set; }
        public int Id => Identifier;
        public string FirstName { get; set; }
        public string LastName { get; set; }
        /// <summary>
        /// Contains primary keys of employees for this manager
        /// </summary>
        public List<int> Employees { get; set; }
    }
    

    Note that each of the above would be in separate files.

    Next, create a list of Employee and Manager which is possible because both implement the same interface.

    public class Mocked
    {
        public static List<IEmployee> PeopleList() =>
        [
            new Employee() { Identifier = 1, FirstName = "Joe", LastName = "Adams" },
            new Employee() { Identifier = 2, FirstName = "Mary", LastName = "Smith" },
            new Manager()
            {
                Identifier = 3, FirstName = "Frank", LastName = "O'Brien",
                Employees = [1,2]
            },
    
    
            new Employee() { Identifier = 5, FirstName = "Lee", LastName = "Fux" },
    
            new Manager()
            {
                Identifier = 6, FirstName = "Sue", LastName = "Gallagher",
                Employees = [8, 10]
            },
    
    
            new Employee() { Identifier = 8, FirstName = "Bob", LastName = "Clime" },
            new Employee() { Identifier = 10, FirstName = "Nancy", LastName = "Burger" }
        ];
    
    }
    

    Then in a console project.

    1. Read the list of employees and managers
    2. Iterate the list, check if a item is a manager using an if statement and pattern matching (which in this case manager is a variable for the current manager.
    internal partial class Program
    {
        static void Main()
        {
            var list = Mocked.PeopleList();
    
            foreach (var employee in list)
            {
                Console.WriteLine($"{employee.FirstName} {employee.LastName}");
                if (employee is Manager manager)
                {
                    foreach (var managerEmployee in manager.Employees)
                    {
                        var emp = list.FirstOrDefault(x => x.Id == managerEmployee);
                        Console.WriteLine($"\t{emp.FirstName} {emp.LastName}");
                    }
                }
            }
    
            Console.ReadLine();
        }
    }
    

    Results

    A1

    Example 2

    Here we use a built in interface so that we can check if a item is between two other items rather than having two different ways to do this.

    Generic language extension

    public static class IComparableExtensions
    {
        public static bool Between<T>(this T value, T lowerValue, T upperValue)
            where T : struct, IComparable<T>
            => Comparer<T>.Default.Compare(value, lowerValue) >= 0 && Comparer<T>.Default.Compare(value, upperValue) <= 0;
    
    }
    

    Usage

    static void Main()
    {
        DateOnly startDate = new(2021, 1, 1);
        DateOnly endDate = new(2021, 12, 31);
    
        if (new DateOnly(2021,3,3).Between(startDate, endDate))
        {
            // do something
        }
        else
        {
            // not between
        }
    
        if (5.Between(4, 10))
        {
            // do something
        }
        else
        {
            // not between
        }
    
        Console.ReadLine();
    }
    
    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.