Вы можете получить доступ к этим свойствам в производном классе через любой доступный член базового класса, тип которого T
(или, конечно, через любой член производного класса, тип которого Account
).
(Нет никакого смысла в общедоступном конструкторе для абстрактного типа, поэтому я изменил его на защищенный.)
Например, предположим, что тип Account
имеет логическое свойство IsOverdue
:
public abstract class BaseUI<T> : INotifyPropertyChanged, IChangeTracking, IDataErrorInfo, ISelectable
where T: new()
{
protected BaseUI() {}
protected BaseUI(T data) { this.Data = data; }
protected T Data { get; private set; }
}
public class AccountUI : BaseUI<Account>
{
public AccountUI() : base() {}
public AccountUI(Account data) : base(data) {}
public void SomeMethod()
{
if (this.Data.IsOverdue)
{
//... handle overdue account
}
}
}
Теперь может быть случай, когда у вас есть ссылка на BaseUI<T>
в общем контексте, поэтому вы не знаете, какой аргумент типа используется во время компиляции. В этом случае вам понадобится абстрактный метод в базовом классе:
public abstract class BaseUI<T> : INotifyPropertyChanged, IChangeTracking, IDataErrorInfo, ISelectable
where T: new()
{
protected BaseUI() {}
protected BaseUI(T data) { this.Data = data; }
protected T Data { get; private set; }
public abstract void SomeMethod();
}
В этом примере вам необходимо добавить ключевое слово override
в объявление AccountUI.SomeMethod:
public class AccountUI : BaseUI<Account>
{
public AccountUI() : base() {}
public AccountUI(Account data) : base(data) {}
public override void SomeMethod()
{
if (this.Data.IsOverdue)
{
//... handle overdue account
}
}
}
Теперь вы можете позвонить SomeMethod
по любой ссылке на BaseUI<T>
. Производный класс отвечает за обеспечение реализации. Как и в первом примере, производный класс знает аргумент типа, предоставленный для T
, и поэтому он может использовать доступные члены этого типа.