Как получить доступ к свойствам T закрытого универсального класса - PullRequest
1 голос
/ 02 апреля 2012

Учитывая открытое определение универсального класса:

public abstract class BaseUI<T> : INotifyPropertyChanged, IChangeTracking, IDataErrorInfo, ISelectable
    where T: new()
{
    public BaseUI()
    {
    }
    public BaseUI(T data)
    {
        // initialization
    }
}

и закрытую реализацию:

public class AccountUI : BaseUI<Account>
{
    public AccountIU()
       : base()
    {

    }
    public AccountUI(Account data)
    : base(data)
    {

    }
}

Как я могу получить доступ к свойствам T / Account?Возможно ли это в 3,5 (т. Е. Без динамического)

1 Ответ

0 голосов
/ 03 апреля 2012

Вы можете получить доступ к этим свойствам в производном классе через любой доступный член базового класса, тип которого 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, и поэтому он может использовать доступные члены этого типа.

...