我正在编写一个 .NET Web 应用程序,管理员可以在其中自定义呈现给用户的各种数据输入表单。管理员可以创建和自定义大约六种不同的字段类型(即文本、数字、下拉列表、文件上传)。所有字段共享一组基本属性/行为(该字段是必需的吗?它是否有默认字段值?)。还有一系列特定于字段的属性/行为(即下拉列表具有数据源属性,但文本字段没有)。为简单起见,我忽略了问题域的许多其他特征。
类层次结构很简单:一个抽象的超类,封装了常见的行为/属性和大约六个处理特定领域内容的具体子类。
每个字段类型都被呈现(即映射到)为特定类型的 .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) 一个好主意吗?