Following is a solution based on the first response from @Kit in Refactoring Code to avoid Type Casting
It avoids any type check with the help of generics.
Calculator Abstraction
public abstract class InvestmentReturnCalculator
{
public double ProfitElement { get; set; }
public abstract double GetInvestmentProfit();
protected double CalculateBaseProfit()
{
double profit = 0;
if (ProfitElement < 5)
{
profit = ProfitElement * 5 / 100;
}
else
{
profit = ProfitElement * 10 / 100;
}
return profit;
}
}
public abstract class InvestmentReturnCalculator<T> : InvestmentReturnCalculator where T : IBusiness
{
public T BusinessType { get; set; }
}
Concrete Calculators
public class RetailInvestmentReturnCalculator : InvestmentReturnCalculator<IRetailBusiness>
{
public RetailInvestmentReturnCalculator(IRetailBusiness retail)
{
BusinessType = retail;
//Business = new BookShop(100);
}
public override double GetInvestmentProfit()
{
ProfitElement = BusinessType.GrossRevenue;
return CalculateBaseProfit();
}
}
public class IntellectualRightsInvestmentReturnCalculator : InvestmentReturnCalculator<IIntellectualRights>
{
public IntellectualRightsInvestmentReturnCalculator(IIntellectualRights intellectual)
{
BusinessType = intellectual;
}
public override double GetInvestmentProfit()
{
ProfitElement = BusinessType.Royalty;
return base.CalculateBaseProfit();
}
}
Business Abstractions
public interface IBusiness
{
InvestmentReturnCalculator GetMyInvestmentReturnCalculator();
}
public abstract class EntityBaseClass
{
}
public interface IRetailBusiness : IBusiness
{
double GrossRevenue { get; set; }
}
public interface IIntellectualRights : IBusiness
{
double Royalty { get; set; }
}
Concrete Businesses
public class EngineDesignPatent : EntityBaseClass, IIntellectualRights
{
public double Royalty { get; set; }
public EngineDesignPatent(double royalty)
{
Royalty = royalty;
}
public InvestmentReturnCalculator GetMyInvestmentReturnCalculator()
{
return new IntellectualRightsInvestmentReturnCalculator(this);
}
}
public class BookShop : EntityBaseClass, IRetailBusiness
{
public double GrossRevenue { get; set; }
public BookShop(double grossRevenue)
{
GrossRevenue = grossRevenue;
}
public InvestmentReturnCalculator GetMyInvestmentReturnCalculator()
{
return new RetailInvestmentReturnCalculator(this);
}
}
public class AudioCDShop : EntityBaseClass, IRetailBusiness
{
public double GrossRevenue { get; set; }
public AudioCDShop(double grossRevenue)
{
GrossRevenue = grossRevenue;
}
public InvestmentReturnCalculator GetMyInvestmentReturnCalculator()
{
return new RetailInvestmentReturnCalculator(this);
}
}
Client
static void Main(string[] args)
{
#region MyBusines
List<IBusiness> allMyProfitableBusiness = new List<IBusiness>();
BookShop bookShop1 = new BookShop(75);
AudioCDShop cd1Shop = new AudioCDShop(80);
EngineDesignPatent enginePatent = new EngineDesignPatent(1200);
BenzolMedicinePatent medicinePatent = new BenzolMedicinePatent(1450);
allMyProfitableBusiness.Add(bookShop1);
allMyProfitableBusiness.Add(cd1Shop);
allMyProfitableBusiness.Add(enginePatent);
allMyProfitableBusiness.Add(medicinePatent);
#endregion
var investmentReturns = allMyProfitableBusiness.Select(bus => bus.GetMyInvestmentReturnCalculator()).ToList();
double totalProfit = 0;
foreach (var profitelement in investmentReturns)
{
totalProfit = totalProfit + profitelement.GetInvestmentProfit();
Console.WriteLine("Profit: {0:c}", profitelement.GetInvestmentProfit());
}
Console.ReadKey();
}