繁体   English   中英

抽象类参考实现类

[英]Abstract class reference implementation classes

我有以下抽象类:

public abstract class Period
{
    public int Id { get; set; }
    protected abstract DateTimeOffset StartDate { get; set; }
    protected abstract DateTimeOffset EndDate { get; set; }
}

使用以下实现:

public class MonthlyPeriod : Period
{
    private DateTimeOffset startDate { get; set; }

    public MonthlyPeriod(DateTimeOffset startDate)
    {
        this.startDate = startDate;
    }

    protected override DateTimeOffset EndDate
    {
        get
        {
            return startDate.AddMonths(1).AddTicks(-1);
        }

        set
        {
            startDate = new DateTime(value.Year, value.Month, 1);
        }
    }

    protected override DateTimeOffset StartDate
    {
        get
        {
            return startDate;
        }

        set
        {
            startDate = new DateTimeOffset(value.Year, value.Month, 1, 0, 0, 0, value.Offset);
        }
    }
}

我想做的是在抽象类中包含以下抽象方法:

public abstract Period GetPreviousPeriod();
public abstract Period GetNextPeriod();

然后在实现中让他们专门返回MonthlyPeriod

public override MonthlyPeriod GetNextPeriod() => new MonthlyPeriod(EndDate.AddDays(1));
public override MonthlyPeriod GetPreviousPeriod() => new MonthlyPeriod(StartDate.AddDays(-1));

然而,这有一个明显的缺陷,即我在抽象类中将方法的类型指定为Period ,而不是MonthlyPeriod

有没有一种直接的方法来定义这种关系?


到目前为止,我得到的最佳解决方案是:

  1. 将抽象方法从public切换到protected
  2. 根据需要使实现的抽象方法产生Period
  3. 在抽象类中定义以下方法:

     public T GetPreviousPeriod<T>() where T : Period { T prevPeriod = GetPreviousPeriod() as T; if (prevPeriod == null) { throw new ArgumentException(); } return prevPeriod; } public T GetNextPeriod<T>() where T : Period { T nextPeriod = GetNextPeriod() as T; if (nextPeriod == null) { throw new ArgumentException(); } return nextPeriod; }

这有效; 然而,它不一定是一个完整的解决方案。 特别是它缺少类型正确的编译时承诺。

如果您创建一些扩展方法,创建这些新实例并返回它们,而不是在基类上强制使用该方法呢?

此外,PeriodFactory 也可以用作“PeriodFactory”看起来也不对,因为它违反了SOLID 中S

public static MonthlyPeriod GetNextPeriod(this MonthlyPeriod period)
{
    return new MonthlyPeriod(period.EndDate);
} 

提出了一个解决方案,该解决方案适用于我原来的问题。

  1. 变化PeriodPeriod<T> where T : Period<T>
  2. 更改public abstract Period GetPreviousPeriod(); public abstract T GetPreviousPeriod();
  3. GetNextPeriod()重复 2。
  4. MonthlyPeriod : Period更改为MonthlyPeriod : Period<MonthlyPeriod>

您可以定义像 IPeriod 这样的接口,并将其作为接口方法中的返回类型。 然后你的具体实现你可以返回 MonthlyPeriod 这将实现接口 IPeriod

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM