C# – Passing an interface in Parameters C#

cinterfaceparameters

image

What is the Benefit of passing in Parameters?
What can we achieve from this?
What is the purpose of?

interface IBankAccount
{
    void PayIn(decimal amount);
    bool Withdraw(decimal amount);
    decimal Balance { get; }
}

interface ITransferBankAccount : IBankAccount
{
    bool TranferTo(IBankAccount destination, decimal amount);
}

class CurrentAccount : ITransferBankAccount
{

    public bool TranferTo(IBankAccount destination, decimal amount)
    {
        bool result;
        result = Withdraw(amount);
        if (result)
        {
            destination.PayIn(amount);
        }
        return result;
    }



    public decimal Balance
    {
        get
        {
            throw new NotImplementedException();
        }
    }

    public void PayIn(decimal amount)
    {
        throw new NotImplementedException();
    }





  public bool Withdraw(decimal amount)
    {
        throw new NotImplementedException();
    }

Demo Code showing This technique
Thanks in Advance

Best Answer

You achieve to implement a principle that says

Program to an interface, not an implementation.

This has been introduced by GoF in their seminal book called Design Patterns. The benefits of adhering to such a practice are the following:

  • clients remain unaware of the specific types of objects they use, as long as the object adheres to the interface
  • clients remain unaware of the classes that implement these objects; clients only know about the abstract class(es) defining the interface

Based on the example you have posted we have two interfaces:

interface IBankAccount
{
    void PayIn(decimal amount);
    bool Withdraw(decimal amount);
    decimal Balance { get; }
}

interface ITransferBankAccount : IBankAccount
{
    bool TranferTo(IBankAccount destination, decimal amount);
}

The interface IBankAccount is composed from two methods and one property that each bank account should have (at least in the perspective of the author of this interface and the problem she/he tried to solve).

Specifically, we should be able to deposit money (PayIn) and withdraw money (Withdraw) from a bank account and last but not least to read the account's balance Balance.

Regarding the second interface, ITransferBankAccount this exhibits a behavior that only some accounts may have. This behavior is to transfer money. We could assume that there are two kinds of bank accounts those from which you can transfer money from one bank account to another and those that you can't, you can only deposit/withdraw from that specific bank account. It's just an assumption tied to this specific problem that Author of theses interfaces she/he tried to solve,

Even before we proceed to the CurrentAccount the benefits of interfaces are evident in the second interface !

We define a behavior, those of transferring money and we don't require the TranferTo method has as it's first parameter a custom type like CurrentAccount or another type. We just require that the first parameter of this method should implement the interface IBankAccount. Just this ! This is enough for us to transfer some money, since we can deposit money to an account by using the PayIn method.

Why the latter is important?

For instance let that we have 3 bank accounts A, B, C. Furthermore, let's assume that the account B and account C are different in terms of business. For instance whenever account B receives an amount of money we should do some extra actions if we compare it with account C. Definetely that means that in order to model this we should have two different classes. BankAccount_B and BankAccount_C. In addition to this let's suppose that whenever we Withdraw money from A to any other account we have to get a specific fee and apply some extra logic. That definitely means that bank account A should be modelled using another class. Let's call it BankAccount_A.

If we suppose that all these classes BankAccount_A, BankAccount_B and BankAccount_C implement the interface IBankAccount and the class BankAccount_A implements the interface ITransferBankAccount, then your can write code like this:

var bankAccountA = new BankAccount_A();

// Deposit $100 in Bank Account A
bankAccountA.PayIn(100);

var bankAccountB = new BankAccount_B();
var bankAccountC = new BankAccount_C();

// Transfer $ 60  to bank account B from A
bankAccountA.TransferTo(bankAccountB, 60);

// Transfer $ 40  to bank account B from A
bankAccountA.TransferTo(bankAccountC, 40);

Suppose that now you didn't have followed this principle and you wanted to implement the above functionality. In this case you should have defined two methods in class BankAccount_A. One for transferring money to bank accounts that are created using the BankAccount_B and one another for transferring money to bank accounts that are created using the BankAccount_C. And what about if you had another requirement for another account D in the future ? You should define another method etc...And this time you should violate one of the principles of SOLID, the Open/Closed principle, software entities … should be open for extension, but closed for modification. Had we used the interface we had been closed for modification :).