我是第一次写一些用户控件,我想知道是否有一种方法可以清理我的一些代码.(如果你想了解我正在做什么的更多背景知识,请看这个问题.)
我有一个BaseControl类,基本上,解析一些XML数据,然后,根据该数据中包含的内容,调用适当的UserControl并在其路上发送数据.这是一个例子:
public partial class BaseControl : User Control
{
protected void Page_Load(object sender, EventArgs e)
{
... //code that parses the data
var renewalDef = effort.Attributes["renewal_def"].Value;
var effortNumber = effort.Attributes["renewal_effort_number"].Value;
if (effortNumber == "1")
{
var effortControl = (NAVLEffort1) Page.LoadControl("~/NAVLSeriesControls/NAVLEffort1.ascx");
effortControl.transactionData = transaction; //'transaction' is a Hashtable object
HtmlContent.Controls.Add(effortControl); //'HtmlContent' is a PlaceHolder control on BaseControl.ascx page
}
if (effortNumber == "2")
{
var effortControl = (NAVLEffort2) Page.LoadControl("~/NAVLSeriesControls/NAVLEffort2.ascx");
effortControl.transactionData = transaction; //'transaction' is a Hashtable object
HtmlContent.Controls.Add(effortControl); //'HtmlContent' is a PlaceHolder control on BaseControl.ascx page
}
if (effortNumber == "3")
{
var effortControl = (NAVLEffort3) Page.LoadControl("~/NAVLSeriesControls/NAVLEffort3.ascx");
effortControl.transactionData = transaction; //'transaction' is a Hashtable object
HtmlContent.Controls.Add(effortControl); //'HtmlContent' is a PlaceHolder control on BaseControl.ascx page
}
// and so on...
}
}
Run Code Online (Sandbox Code Playgroud)
这不是我写的实际代码,它只是我可以前进的一个例子.我想做的是更像这样的事情:
...
var effortControlFileString = string.Format("~/NAVLSeriesControls/{0}Effort{1}.ascx", renewalDef, effortNumber);
var effortControl = (renewalDef + "Effort" + effortNumber) Page.LoadControl(effortControlFileString);
effortControl.transactionData = transaction;
HtmlContent.Controls.Add(effortControl)
...
Run Code Online (Sandbox Code Playgroud)
我有什么想法可以清理这个烂摊子?
您可以让所有控件实现一个公共接口并转换为该接口.
public interface IMyInterface
{
object TransactionData
{
get;
set;
}
}
Control effortControl = Page.LoadControl(path);
HtmlContent.Controls.Add(effortControl);
IMyInterface obj = (IMyInterface)effortControl;
obj.TransactionData = transaction;
Run Code Online (Sandbox Code Playgroud)
在在线IDE中查看此工作示例.
您还可以使用抽象基类并使用相同的结果强制转换为该类型.您将需要使用继承自的基类UserControl.这将避免有两个对象引用(如上例所示),因为它可以转换为UserControl.
上面的例子变成:
MyCustomControlType c = (MyCustomControlType)Page.LoadControl(path);
HtmlContent.Controls.Add(c);
c.TransactionData = transaction;
Run Code Online (Sandbox Code Playgroud)
如果每种控件类型的逻辑不同,那么您可能需要转换为每个特定类型(基本上是一个大的if/else块)并单独处理每个控件.换句话说,如果您需要根据控件的类型执行不同的操作,则需要具有类型感知的逻辑.
为了完整起见,我会提到你也可以使用DLR,但我建议反对它.您将放弃编译时类型的安全性和性能以减少一些代码.