【发布时间】:2011-01-01 18:11:23
【问题描述】:
我编写了管理表单的 ASP.NET 页面。它们基于以下基类。
public abstract class FormPageBase<TInterface, TModel> : Page, IKeywordProvider
where TModel:ActiveRecordBase<MasterForm>, TInterface, new()
where TInterface:IMasterForm
{
public TInterface FormData { get; set; }
}
这里有一个示例子类:
public partial class PersonalDataFormPage : FormPageBase<IPersonalDataForm, PersonalDataForm>, IHasFormData<IPersonalDataForm>, IHasContact
{
}
下面我在页面上有一个用户控件,我想从页面“使用”“FormData”,以便它可以读取/写入它。
然后,我想要在所有表单子类的基本接口上操作一个更“通用”的用户控件... IMasterForm
但是当用户控件尝试转换 Page.FormData 时(尝试将页面转换为 IHasFormData<IMasterForm> 它告诉我该页面是 IHasFormData<IFormSubclass>,即使我对 IFormSubclass 有一个约束说它也是 IMasterForm
我是否可以从泛型子类转换为泛型超类,或者这是“协方差”和 C# 4.0 的东西?
public abstract class FormControlBase<T> : UserControl, IKeywordProvider
where T:IMasterForm
{
protected T FormData { get; set; }
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
//This cast is failing when my common control's T does not exactly match
// the T of the Page.. even though the common controls TInterface is a base interface to the
//pages TInterface
FormData = ((IHasFormData<T>) Page).FormData;
if (!IsPostBack)
{
PopulateBaseListData();
BindDataToControls();
}
}
protected abstract void PopulateBaseListData();
protected abstract void BindDataToControls();
public abstract void SaveControlsToData();
#region IKeywordProvider
public List<IKeyword> GetKeywords(string categoryName)
{
if(!(Page is IKeywordProvider ))
throw new InvalidOperationException("Page is not IKeywordProvider");
return ((IKeywordProvider) Page).GetKeywords(categoryName);
}
#endregion
}
【问题讨论】:
-
Skeeter 在 c# 中深入讨论了这一点。值得一看。
-
我确实想到了这一点。也许对于我自己的个人应用程序,我可能会为 lulz 做它
标签: c# .net generics .net-3.5 covariance