2012-04-02 6 views
1

のプロパティにTにアクセスする方法:私はT /アカウントのプロパティにアクセスするにはどうすればよいオープンジェネリッククラス定義のを考えると、閉じたジェネリッククラス

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

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

    } 
} 

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

との閉じた実装?

+0

*ここでは*プロパティにアクセスする必要がありますか?それらは制約付きインターフェイスの一部として含まれていますか? –

+0

(参考のため、最初のコンストラクタに入力ミスがあります) – Bridge

+0

複数のインスタンスでクラスにアクセスする必要がありますが、ほとんどはUIなどのコンシューマにあります。 –

答えて

0

タイプがTの基本クラスのアクセス可能なメンバーから派生クラスのこれらのプロパティにアクセスすることができます(もちろん、派生クラスの任意のメンバーを介して)そのタイプはAccountです)。

は(抽象型のパブリックコンストラクタにはポイントはありませんので、私は保護にこれらを変更しました。)例えば

Accountタイプはboolean型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(); 
} 

、あなたがAccountUI.SomeMethodの宣言にoverrideキーワードを追加する必要があります。

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 
     } 
    } 
} 

BaseUI<T>への参照にはSomeMethodと電話することができます。派生クラスは、実装の提供を担当します。最初の例と同様に、派生クラスはTで指定された型引数を知っているため、その型のアクセス可能なメンバを使用できます。

+0

ありがとうございます。おそらく私は私の元の考えを詳しく述べるべきです。私はAccount.Propertyのようなことができることを期待していました。プロパティはTのプロパティです。言い換えれば、Dataフィールドをなくし、ジェネリック型のプロパティに直接移動します。そうでなければ私は、実装することによって、私はあなたがC#4と大きい、中dynamic'タイプ '使用していることを行うことができると思いT –

+0

@JohnWollnerを使用することによって、私は避けるようにしようとしているものの一つであるすべてのプロパティを再作成する必要があり' IDynamicMetaObjectProvider'をBaseUIクラスに追加します。それはおそらくそれが価値があるよりはるかに多くのトラブルです。あなたのBaseUIクラスが 'Update()'メソッドを持っていて、基礎となるビジネスオブジェクトもそうであれば、あいまいさに陥るかもしれません。以前のC#バージョンでも動作するもう1つのアプローチは、実行時にILを動的に生成するか、またはおそらく部分クラスを使用して設計時にC#を生成することです。 – phoog

関連する問題