3

私は初めていくつかのユーザーコントロールを書いていますが、コードの一部をクリーンアップする方法があるかどうか疑問に思っています。(私が取り組んでいることの背景についてもっと知りたい場合は、この質問を参照してください。)

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...
    }
}

これは私が書いた実際のコードではなく、私が向かうことができる場所の単なる例です。私がやりたいのは、もっと次のようなものです。

...
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)
...

この混乱をどのようにクリーンアップできるかについてのアイデアはありますか?

4

2 に答える 2

5

インターフェース

すべてのコントロールに共通のインターフェースを実装させ、それにキャストさせることができます。

public interface IMyInterface
{
    object TransactionData
    {
       get;
       set;
    }
}

Control effortControl = Page.LoadControl(path);
HtmlContent.Controls.Add(effortControl);

IMyInterface obj = (IMyInterface)effortControl;
obj.TransactionData = transaction;

オンラインIDEでこの動作例を参照してください。

基本クラス

抽象基本クラスを使用して、同じ結果でその型にキャストすることもできます。から継承する基本クラスを使用する必要がありますUserControl。これにより、にキャストできるため、(上記の例のように)2つのオブジェクト参照が回避されUserControlます。

上記の例は次のようになります。

MyCustomControlType c = (MyCustomControlType)Page.LoadControl(path);
HtmlContent.Controls.Add(c);
c.TransactionData = transaction;

各コントロールタイプのロジックが異なる場合は、おそらく各特定のタイプ(基本的には大きなif / elseブロック)にキャストし、各コントロールを個別に処理する必要があります。つまり、コントロールのタイプに基づいてさまざまなアクションを実行する必要がある場合は、タイプを認識するロジックが必要になります。

完全を期すために、DLRを使用することもできますが、反対することをお勧めします。少しのコードを減らすために、コンパイル時の型の安全性とパフォーマンスをあきらめることになります。

于 2012-04-06T21:18:01.373 に答える
0

インターフェイスを作成し、コントロールをhtmlページに追加できます。元:

private Control _contentControl;

_contentControl = Page.LoadControl("~/Administration/Projects/UserControls/" + controlName);
        ((IEditProjectControl)_contentControl).ProjectId = ProjectId;
        plhContent.Controls.Clear();
        plhContent.Controls.Add( _contentControl );
        _contentControl.ID = "ctlContent";
        Image2.Visible = ((IEditProjectControl)_contentControl).ShowSaveButton;
        SaveButton.Visible = ((IEditProjectControl)_contentControl).ShowSaveButton;
        ((IEditProjectControl)_contentControl).Initialize();
于 2014-06-03T13:41:50.770 に答える