【问题标题】:How can I optimize the structure of my classes如何优化我的课程结构
【发布时间】:2020-06-28 08:21:11
【问题描述】:

我正在努力定义我的类的结构

我创建了ObjMetaClass 类的对象列表。其中包含有关其对象 points 的一些元信息(pointsObjMetaClass 类的属性)。
但是points可以有两种类型,一种是TwoPointsPattern类,另一种是ThreePointsPattern

我担心的是,每当我想访问任何项目时,我首先需要检查当前项目中存储了哪个项目以进行投射(是TwoPointsPattern还是ThreePointsPattern

List<ObjMetaClass> objList = new List<ObjMetaClass>();
// some items
objList.Add(new ObjMetaClass(new TwoPointsPattern(...), isTwoPointsPattern:true, rate:124));
objList.Add(new ObjMetaClass(new ThreePointsPattern(...), isTwoPointsPattern:false, rate:654));

// access items from list
for (int i = 0; i < objList.Count; i++)
{
    // check for casting object
    if(objList[i].isTwoPointsPattern)
        TwoPointsPattern temp = objList[i].points as TwoPointsPattern;
        /* some logic or function call */
    else
        ThreePointsPattern temp = objList[i].points as ThreePointsPattern;
        /* some logic or function call */
}

有没有更好的方法来改进它或避免if 检查?有什么建议,欢迎

类的结构
对象元类

public class ObjMetaClass
{
    public object points { get; internal set; }
    public bool isTwoPointsPattern { get; internal set; }
    internal int rate { get; set; }

    public ObjMetaClass(object points, bool isTwoPointsPattern, int rate)
    {
        // check expected type of points object
        if (points.GetType() != typeof(TwoPointsPattern) &&
            points.GetType() != typeof(ThreePointsPattern))
            throw new ArgumentException("Expected types TwoPointsPattern and ThreePointsPattern");

        this.points = points;
        this.isTwoPointsPattern = isTwoPointsPattern;
        this.rate = rate;
    }
}

TwoPointsPattern 和 ThreePointsPattern

public class TwoPointsPattern
{
    public double FirstDate { get; internal set; }
    public double FirstPrice { get; internal set; }

    public double SecondDate { get; internal set; }
    public double SecondPrice { get; internal set; }

    public TwoPointsPattern(double FirstDate, double FirstPrice, double SecondDate, double SecondPrice)
    {
        this.FirstDate = FirstDate;     this.FirstPrice = FirstPrice;
        this.SecondDate = SecondDate;   this.SecondPrice = SecondPrice;
    }
}

public class ThreePointsPattern
{
    public double FirstDate { get; internal set; }
    public double FirstPrice { get; internal set; }

    public double SecondDate { get; internal set; }
    public double SecondPrice { get; internal set; }

    public double ThirdDate { get; internal set; }
    public double ThirdPrice { get; internal set; }

    public ThreePointsPattern(double FirstDate, double FirstPrice, double SecondDate, double SecondPrice,
                              double ThirdDate, double ThirdPrice)
    {
        this.FirstDate = FirstDate;     this.FirstPrice = FirstPrice;
        this.SecondDate = SecondDate;   this.SecondPrice = SecondPrice;
        this.ThirdDate = ThirdDate;     this.ThirdPrice = ThirdPrice;
    }
}

【问题讨论】:

  • 代码到抽象,而不是实现。 /* some logic or function call */ 中的逻辑或函数调用是什么?如果可以抽象此逻辑(GetAveragePrice()、GetMaxPriceAndDate()、GetMinPriceDate 等),那么您可以拥有一个 PricePattern 基类,而不必针对该属性进行测试(或通过类型检查),您可以调用这些基本方法而无需甚至知道类的实际类型
  • @OguzOzgul 他们都有不同的逻辑流程。对于不同的类型。我无法抽象所有逻辑
  • 您需要为我们分享这些逻辑流程,看看是否有什么可以做的。好的,至少不要检查属性,检查类型。目前,由于只有两种类型,布尔值isTwoPointsPattern 足以区分您的两种类型。如果稍后引入 FourPointsPattern 怎么办?你至少可以这样做:if(objList[i].GetType() == typeof(TwoPointsPattern))
  • @OguzOzgul 谢谢你的建议。我不分享这个流程逻辑。否则这将是更复杂的问题。我正在尝试 Miamy 的答案,我认为它会起作用
  • 是的,它会的。 :)

标签: c# .net inheritance optimization multiple-inheritance


【解决方案1】:

第一种方法 - 继承:

public class TwoPointsPattern
{
  public double FirstDate { get; internal set; }
  public double FirstPrice { get; internal set; }

  public double SecondDate { get; internal set; }
  public double SecondPrice { get; internal set; }

  public TwoPointsPattern(double FirstDate, double FirstPrice, double SecondDate, 
    double SecondPrice)
  {
      this.FirstDate = FirstDate;     this.FirstPrice = FirstPrice;
      this.SecondDate = SecondDate;   this.SecondPrice = SecondPrice;
  }

  public virtual void DoSomeLogic()
  {...}
}

public class ThreePointsPattern : TwoPointsPattern
{
   public double ThirdDate { get; internal set; }
   public double ThirdPrice { get; internal set; }

   public ThreePointsPattern(double FirstDate, double FirstPrice,
             double SecondDate, double SecondPrice,  double ThirdDate, double ThirdPrice) 
           : base(FirstDate, FirstPrice, SecondDate, SecondPrice) 
   {
      this.ThirdDate = ThirdDate;     this.ThirdPrice = ThirdPrice;
   }

   public override void DoSomeLogic()
   {...}
}

public class ObjMetaClass
{
   public TwoPointsPattern points { get; internal set; }
   ...
 }

// access items from list
for (int i = 0; i < objList.Count; i++)
{
   objList[i].points.DoSomeLogic();
}

第二种方法 - 接口:

public interface ISomeLogic
{
   void DoSomeLogic();
}

public class TwoPointsPattern : ISomeLogic
{
   public void DoSomeLogic();
}

public class ThreePointsPattern : ISomeLogic
{
   public void DoSomeLogic();
}

public class ObjMetaClass
{
    public ISomeLogic points { get; internal set; }
    ...
}

// access items from list
for (int i = 0; i < objList.Count; i++)
{
    objList[i].points.DoSomeLogic();
}

从您显示的代码看来,ThreePointsPattern 可以是 TwoPointsPattern 的子级,所以如果我没有遗漏任何内容,第一种方法会更好。

【讨论】:

  • 谢谢,是的,ThreePointsPattern 可以是TwoPointsPattern 的孩子
猜你喜欢
  • 1970-01-01
  • 2014-06-08
  • 1970-01-01
  • 2021-09-23
  • 1970-01-01
  • 1970-01-01
  • 2010-12-28
  • 1970-01-01
  • 2011-03-09
相关资源
最近更新 更多