如何避免冗余代码没有不必要的genericsgenerics
在问题“ C#generics:将generics类型转换为值类型 ”中,Eric Lippert和Jon Skeet都表示以下方法不是一个好的解决方案
//return new T { BusinessType = (U)(object)this }; //Eric Lippert answer (Not suggested) //return new T { BusinessType = (dynamic)this }; //Jon Skeet answer (Not suggested)
我的C#.Net 4.0解决方案中存在code redundancy
问题。 在EngineDesignPatent
和BenzolMedicinePatent
重复了GetCalculator()
方法。
public override InvestmentReturnCalculator GetCalculator() { IntellectualRightsInvestmentReturnCalculator c = new IntellectualRightsInvestmentReturnCalculator(); c.BusinessType = this; return c; }
虽然不是更可取,但@Kit提到了以下方法来避免“ 重构代码以避免类型转换 ”中的冗余。
//BusinessBaseClass public abstract class BusinessBaseClass : EntityBaseClass, IBusiness where T : InvestmentReturnCalculator, new() where U : IBusiness { public virtual InvestmentReturnCalculator GetCalculator() { //return new T { BusinessType = (U)(object)this }; //Eric Lippert answer (Not suggested) return new T { BusinessType = (dynamic)this }; //Jon Skeet answer (Not suggested) } }
题
没有双重投射方法,避免代码冗余的替代方法是什么?
码
业务类型抽象
public interface IBusiness { InvestmentReturnCalculator GetCalculator(); } public interface IRetailBusiness : IBusiness { double GrossRevenue { get; set; } } public interface IIntellectualRights : IBusiness { double Royalty { get; set; } } public abstract class EntityBaseClass { }
计算器
public abstract class InvestmentReturnCalculator { public abstract double ProfitElement { get; } public double GetInvestmentProfit() { double profit = 0; if (ProfitElement < 5) { profit = ProfitElement * 5 / 100; } else { profit = ProfitElement * 10 / 100; } return profit; } } public abstract class InvestmentReturnCalculator : InvestmentReturnCalculator where T : IBusiness { public T BusinessType { get; set; } } public class RetailInvestmentReturnCalculator : InvestmentReturnCalculator { public override double ProfitElement { get { return BusinessType.GrossRevenue; } } } public class IntellectualRightsInvestmentReturnCalculator : InvestmentReturnCalculator { public override double ProfitElement { get { return BusinessType.Royalty; } } }
具体业务类型Entites
public class EngineDesignPatent : BusinessBaseClass, IIntellectualRights { public double Royalty { get; set; } public EngineDesignPatent(double royalty) { Royalty = royalty; } //public override InvestmentReturnCalculator GetCalculator() //{ // IntellectualRightsInvestmentReturnCalculator c = new IntellectualRightsInvestmentReturnCalculator(); // c.BusinessType = this; // return c; //} } public class BenzolMedicinePatent : BusinessBaseClass, IIntellectualRights { public double Royalty { get; set; } public BenzolMedicinePatent(double royalty) { Royalty = royalty; } //public override InvestmentReturnCalculator GetCalculator() //{ // IntellectualRightsInvestmentReturnCalculator c = new IntellectualRightsInvestmentReturnCalculator(); // c.BusinessType = this; // return c; //} } public class BookShop : BusinessBaseClass, IRetailBusiness { public double GrossRevenue { get; set; } public BookShop(double grossRevenue) { GrossRevenue = grossRevenue; } //public override InvestmentReturnCalculator GetCalculator() //{ // RetailInvestmentReturnCalculator c = new RetailInvestmentReturnCalculator(); // c.BusinessType = this; // return c; //} }
客户
static void Main(string[] args) { #region MyBusines List allMyProfitableBusiness = new List(); BookShop bookShop1 = new BookShop(75); EngineDesignPatent enginePatent = new EngineDesignPatent(1200); BenzolMedicinePatent medicinePatent = new BenzolMedicinePatent(1450); allMyProfitableBusiness.Add(bookShop1); allMyProfitableBusiness.Add(enginePatent); allMyProfitableBusiness.Add(medicinePatent); #endregion var investmentReturns = allMyProfitableBusiness.Select(bus => bus.GetCalculator()).ToList(); double totalProfit = 0; foreach (var profitelement in investmentReturns) { totalProfit = totalProfit + profitelement.GetInvestmentProfit(); Console.WriteLine("Profit: {0:c}", profitelement.GetInvestmentProfit()); } Console.ReadKey(); }
参考
- C#generics:将generics类型转换为值类型
- 重构代码以避免类型转换
- 重构类设计以传达设计意图