摘要 class 参考实现 classes
Abstract class reference implementation classes
我有以下摘要class:
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);
}
}
}
我想做的是在摘要中包含以下抽象方法 class:
public abstract Period GetPreviousPeriod();
public abstract Period GetNextPeriod();
然后在实现中让它们 return MonthlyPeriod
特别是:
public override MonthlyPeriod GetNextPeriod() => new MonthlyPeriod(EndDate.AddDays(1));
public override MonthlyPeriod GetPreviousPeriod() => new MonthlyPeriod(StartDate.AddDays(-1));
然而,这有一个明显的缺陷,即我在摘要 class 中将方法的类型指定为 Period
,而不是 MonthlyPeriod
。
是否有直接的方法来定义这种类型的关系?
到目前为止我得到的最佳解决方案是:
- 将抽象方法从
public
切换到 protected
。
- 根据需要使已实现的抽象方法产生
Period
。
在摘要中class定义以下方法:
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;
}
这行得通;但是,它不一定是一个完整的解决方案。特别是它缺少类型正确的编译时承诺。
您可以定义一个像 IPeriod 这样的接口,并将其作为接口方法中的 return 类型。然后你的具体实现你可以 return MonthlyPeriod 这将实现接口 IPeriod
与其在基础 class 上强制使用该方法,不如创建一些扩展方法来创建这些新实例并 returns 它们呢?
此外,句点也用作 "PeriodFactory" 看起来不对,因为它违反了 S in SOLID。
public static MonthlyPeriod GetNextPeriod(this MonthlyPeriod period)
{
return new MonthlyPeriod(period.EndDate);
}
想出了一个解决方案,适用于我原来的问题。
- 将
Period
更改为Period<T> where T : Period<T>
- 将
public abstract Period GetPreviousPeriod();
更改为public abstract T GetPreviousPeriod();
- 为
GetNextPeriod()
重复 2。
- 将
MonthlyPeriod : Period
更改为 MonthlyPeriod : Period<MonthlyPeriod>
。
我有以下摘要class:
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);
}
}
}
我想做的是在摘要中包含以下抽象方法 class:
public abstract Period GetPreviousPeriod();
public abstract Period GetNextPeriod();
然后在实现中让它们 return MonthlyPeriod
特别是:
public override MonthlyPeriod GetNextPeriod() => new MonthlyPeriod(EndDate.AddDays(1));
public override MonthlyPeriod GetPreviousPeriod() => new MonthlyPeriod(StartDate.AddDays(-1));
然而,这有一个明显的缺陷,即我在摘要 class 中将方法的类型指定为 Period
,而不是 MonthlyPeriod
。
是否有直接的方法来定义这种类型的关系?
到目前为止我得到的最佳解决方案是:
- 将抽象方法从
public
切换到protected
。 - 根据需要使已实现的抽象方法产生
Period
。 在摘要中class定义以下方法:
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; }
这行得通;但是,它不一定是一个完整的解决方案。特别是它缺少类型正确的编译时承诺。
您可以定义一个像 IPeriod 这样的接口,并将其作为接口方法中的 return 类型。然后你的具体实现你可以 return MonthlyPeriod 这将实现接口 IPeriod
与其在基础 class 上强制使用该方法,不如创建一些扩展方法来创建这些新实例并 returns 它们呢?
此外,句点也用作 "PeriodFactory" 看起来不对,因为它违反了 S in SOLID。
public static MonthlyPeriod GetNextPeriod(this MonthlyPeriod period)
{
return new MonthlyPeriod(period.EndDate);
}
想出了一个解决方案,适用于我原来的问题。
- 将
Period
更改为Period<T> where T : Period<T>
- 将
public abstract Period GetPreviousPeriod();
更改为public abstract T GetPreviousPeriod();
- 为
GetNextPeriod()
重复 2。 - 将
MonthlyPeriod : Period
更改为MonthlyPeriod : Period<MonthlyPeriod>
。