Я написал страницы 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
Но когда usercontrol пытается привести 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
}