Я получил следующий абстрактный класс:абстрактных классов реализации ссылочного класса
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
.
Есть ли прямой способ определить этот тип отношений?
Лучшее решение у меня до сих пор это:
- переключатель абстрактные методы от
public
кprotected
. - Сделать реализованные абстрактные методы производят
Period
, при необходимости. В абстрактном классе определяют следующие методы:
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; }
Это работает; однако это не обязательно полное решение. В частности, не хватает времени компиляции, чтобы тип был правильным.
его в природе дженериков, вы не сможете получить ту компиляцию, которую я боюсь.Представьте себе, что я использую вашу сборку, где 'GetNextPeriod' уже скомпилирован, и я поставляю свой собственный класс, производный от Period .. –
Да, это в значительной степени то, чего я пытаюсь избежать :(Я думал о маркировке Period как 'internal' , но это примерно так же хорошо, как я думаю, я мог бы получить, а затем это вроде потеряет ценность как абстрактный класс. –