Generics 如何访问封闭泛型类的属性T
给定以下的开放泛型类定义:Generics 如何访问封闭泛型类的属性T,generics,properties,c#-3.0,Generics,Properties,C# 3.0,给定以下的开放泛型类定义: public abstract class BaseUI<T> : INotifyPropertyChanged, IChangeTracking, IDataErrorInfo, ISelectable where T: new() { public BaseUI() { } public BaseUI(T data) { // initialization } } 公共抽象类Ba
public abstract class BaseUI<T> : INotifyPropertyChanged, IChangeTracking, IDataErrorInfo, ISelectable
where T: new()
{
public BaseUI()
{
}
public BaseUI(T data)
{
// initialization
}
}
公共抽象类BaseUI:INotifyPropertyChanged、IChangeTracking、IDataErrorInfo、ISelectable
其中T:new()
{
公共BaseUI()
{
}
公共BaseUI(T数据)
{
//初始化
}
}
以及封闭式实施:
public class AccountUI : BaseUI<Account>
{
public AccountIU()
: base()
{
}
public AccountUI(Account data)
: base(data)
{
}
}
公共类AccountUI:BaseUI
{
公共会计
:base()
{
}
公共帐户用户界面(帐户数据)
:基本(数据)
{
}
}
如何访问T/Account的属性?这在3.5(即w/o dynamic)中是否可能您可以通过类型为
T
的基类的任何可访问成员(当然,也可以通过类型为Account
的派生类的任何成员)访问派生类中的这些属性
(抽象类型上的公共构造函数没有意义,所以我将它们改为protected。)
例如,假设帐户
类型具有布尔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
的任何引用调用SomeMethod
。派生类负责提供实现。与第一个示例一样,派生类知道为T
提供的类型参数,因此它可以使用该类型的可访问成员。在哪里需要访问属性,以及它们是否作为任何受约束接口的一部分包含?(仅供参考,您的第一个构造函数中有一个输入错误。)我需要在多个实例中访问它们,有些是类内部的,但大多数是在UI或类似的消费者银行中进行输入。也许我应该详细说明我最初的想法。我希望能够做一些类似Account.Property的事情,其中Property是T上的属性。换句话说,去掉数据字段,直接转到泛型类型的属性。否则,我必须重新创建所有属性,这是我试图通过使用T@JohnWollner我认为您可以在C#4或更高版本中使用dynamic
type,通过在BaseUI类上实现IDynamicMetaObjectProvider
来实现这一点。然而,这可能比它的价值要麻烦得多。例如,如果您的BaseUI类有一个Update()
方法,底层业务对象也有此方法,那么您可能会遇到歧义。另一种方法也适用于早期的C#版本,即在运行时动态发出IL,或在设计时生成C#,可能使用分部类。
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();
}
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
}
}
}