2012-04-02 76 views
1

的特性給定t開放式泛型類定義的:如何進入封閉泛型類

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 /帳戶的屬性?這是可能的3.5(即無動態)

+0

*您需要訪問屬性,並且它們是否包含在任何受限接口中? – 2012-04-02 11:36:29

+0

(僅供參考,您在第一個構造函數中存在拼寫錯誤。) – Bridge 2012-04-02 11:39:52

+0

我需要在多個實例中訪問它們,其中一些內部類但主要在UI或類似的消費者中 – 2012-04-10 12:42:03

回答

0

您可以通過基類的任何可訪問的成員訪問派生類中的這些屬性,其類型是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 
     } 
    } 
} 

現在您可以致電SomeMethodBaseUI<T>的任何引用。派生類負責提供實現。和第一個例子一樣,派生類知道爲T提供的類型參數,因此它可以使用該類型的可訪問成員。

+0

感謝您的輸入。也許我應該詳細闡述一下我最初的想法。我希望能夠做一些像Account.Property的事情,其中​​Property是T上的一個屬性。換句話說,爲了消除Data域並直接轉到泛型類型的屬性。否則,我必須採用t – 2012-04-10 12:43:31

+0

@JohnWollner我想你可以做,在C#4和更高,使用'dynamic'類型,通過實施重新創建所有這些是的事情,我試圖避免一個屬性'您的BaseUI類上的IDynamicMetaObjectProvider'。然而,這可能比它的價值更麻煩。您還可能碰上不確定性,如果你的BaseUI類有,例如,'更新()'方法,所以沒有基礎業務對象。另一種方法,這也適用於早期C#版本,將在運行時動態發射IL,或產生在設計時C#中,可能使用部分類。 – phoog 2012-04-10 16:19:57