我正在编写一个.NET Web应用程序,管理员可以自定义呈现给用户的各种数据输入表单。管理员可以创建和自定义大约半打不同类型的字段(例如文本、数字、下拉列表、文件上传)。所有字段共享一组基本属性/行为(字段是否必填?它是否有默认字段值?)。还有一系列特定于字段的属性/行为(例如下拉列表具有数据源属性,但文本字段没有)。出于简单起见,我省略了许多问题域的其他特征。
类层次结构很简单:一个抽象超类封装了常见的行为/属性,以及大约半打处理特定于字段的内容的具体子类。
每种字段类型都呈现为特定类型的.NET服务器控件(即映射到),所有这些控件都派生自System.Web.UI.Control。
我创建了以下代码来映射字段域对象和其对应的UI控件之间的值:
我希望能够依靠.NET在运行时使用正在使用的特定子类来调用相应的重载方法。例如:
类层次结构很简单:一个抽象超类封装了常见的行为/属性,以及大约半打处理特定于字段的内容的具体子类。
每种字段类型都呈现为特定类型的.NET服务器控件(即映射到),所有这些控件都派生自System.Web.UI.Control。
我创建了以下代码来映射字段域对象和其对应的UI控件之间的值:
public static void Bind(Control control, IList<DocumentFieldBase> fieldBaseList)
foreach (DocumentFieldBase fieldBase in fields){
if (typeof (DocumentFieldText).IsInstanceOfType(fieldBase)){
TextBox textbox = (TextBox) control;
textbox.Text = (fieldBase as DocumentFieldText).GetValue();
}
if (typeof (DocumentFieldDropDown).IsInstanceOfType(fieldBase)){
DropDown dropDown= (DropDown) control;
dropDown.Text = (fieldBase as DocumentFieldSelectOne).GetValue().Text;
dropDown.DataSource= (fieldBase as DocumentFieldSelectOne).DataSource;
dropDown.Id= (fieldBase as DocumentFieldSelectOne).GetValue().Id;
}
//more if statements left out for brevity
}
}
我希望摆脱那些进行类型检查的可怕 if 语句。我的方法是使用子类类型为每个字段/控件组合创建方法重载。例如:
public static void Bind(TextBox control, DocumentFieldText fieldText){
//some implementation code
}
public static void Bind(DropDown control, DocumentFieldDropDown fieldDropDown){
//some implementation code
}
我希望能够依靠.NET在运行时使用正在使用的特定子类来调用相应的重载方法。例如:
foreach (DocumentFieldBase field in fields){
Control control = FindControl(field.Identifier);
Bind(control, field)
}
很不幸,当我尝试这样做时,编译器报错了:
参数'1':无法将'System.Web.UI.Control'转换为'TextBox'。
如果我必须将第一个参数强制转换为TextBox,那么我又要自己执行类型检查,这就打败了整个练习的目的。
我试图实现的目标是a)可能的和b)一个好主意吗?