Click here to Skip to main content
15,885,278 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I am trying to implement generic code to handle savings and checkin bank accounts. This code should work as per below conditions.

1) Common Add() and Withdraw() methods for savings and checkin accounts.
2) Common IComparable<T> implementation for comparing any two accounts based on balance.
3) There shouldn't be any hard-coded type casting.

C#
interface IBankAccount
        {
            decimal Balance { get; set; }
            string AccountType { get; set; }
            bool Add(decimal amount);
            bool Withdraw(decimal amount);        
        }
    
        abstract class BankAccount<T> : IBankAccount, IComparable<T> where T : IBankAccount
        {
            public decimal Balance { get; set; } = 0;
    
            public string AccountType { get; set; } = string.Empty;
    
            public bool Add(decimal amount)
            {
                Balance += amount;
                return true;
            }
    
            public bool Withdraw(decimal amount)
            {
                if ((Balance - amount) < 0)
                {
                    return false;
                }
    
                Balance -= amount;
                return true;
            }       
    
            public int CompareTo(T other)
            {
                if (this.Balance == other.Balance)
                {
                    return 1;
                }
                else
                {
                    return 0;
                }
            }
        }
    
        class SavingsAccount : BankAccount<SavingsAccount>
        {
            public SavingsAccount()
            {
                this.Balance = 500;
                this.AccountType = "Savings";
            }
        }
    
        class CheckInAccount : BankAccount<CheckInAccount>
        {
            public CheckInAccount()
            {
                this.Balance = 1000;
                this.AccountType = "CheckIn";
            }
        }  
        
        class Customer 
        {
            public IList<IBankAccount> accounts = new List<IBankAccount>();
            public void CreateAccount<T>() where T : BankAccount<T>, new()
            {            
                T account = new T();
                accounts.Add(account);           
            }      
        }
    
     class Program
        {
            static void Main(string[] args)
            {
                Customer customer1 = new Customer();
                customer1.CreateAccount<SavingsAccount>();
                customer1.CreateAccount<CheckInAccount>();
    
                Customer customer2 = new Customer();
                customer2.CreateAccount<CheckInAccount>();
    
                Customer customer3 = new Customer();
                customer3.CreateAccount<SavingsAccount>();
                customer3.CreateAccount<CheckInAccount>();
    
                customer3.accounts[0].Add(500);
    
                // How can I compare customer3.accounts[0] and customer1.accounts[1] equality as I can't access CompareTo() method?
    
                Console.Read();
            }
        }


Please suggest a way to access CompareTo() method? I am fine with IBankAccount interface inheriting IComparable<T> like below as well if that is easy solution.

C#
interface IBankAccount<T> : IComprable<T>
    {
    }


What I have tried:

I tried IBankAccount interface inheriting IComparable interface and couple of other things as mentioned in the question. But in all cases either I ended up with hardcoded type casting or not able to access expected methods.
Posted
Updated 3-Nov-16 5:16am

have you abstracted your code too much- hehe?

No jokes aside, if you write Code like this, you should be quite firm with OOP concepts and implementations - just because something is good practice doesn't mean you have to use it...

So let's see what you have here: a list of IBankAccounts on your customers - do this Interface have a compare method - no. so you can't access it - logical
What you want: a list of BankAccount<t> instances on your customers which have a your generic compare implementation. All good.
But maybe you plan to add other BankAccount<t> implementations (unlikely, contradicts the purpose here) so do like phil.o showed you above - make every implementer of IBankAccount<t> also implement IComparable<ibankaccount<t>>. As he said, I don't see any need for generics here too, just normal inheritance, though I don't know what you plan to do with this (so maybe you have other good reasons)

Does this help to fix your code now?

Kind regards Johannes
 
Share this answer
 
v2
Comments
rajasekhara reddy 3-Nov-16 12:11pm    
Yeap. I agree 100% with your comments. Thanks for opening up new doors.
Your interface should be
C#
interface IBankAccount<T> : IComparable<IBankAccount<T>>
{ }

abstract class BankAccount<T> : IBankAccount<T>
{
   public int Compare(IBankAccount<T> other)
   {
      return Balance.CompareTo(other.Balance);
   }
}

But, I'm not sure you need a generic here. Inheritance is sufficient.
 
Share this answer
 
v4

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900