如何避免冗余代码没有不必要的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问题。 在EngineDesignPatentBenzolMedicinePatent重复了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(); } 

参考

  1. C#generics:将generics类型转换为值类型
  2. 重构代码以避免类型转换
  3. 重构类设计以传达设计意图